Eliminazione collettiva per tabella di grandi dimensioni in MySQL


9

Ho una tabella di notifica che contiene circa 100 milioni di righe host in Amazon RDS con 1000 IOPS e desidero eliminare quelle righe più vecchie di un mese.

In tal caso DELETE FROM NOTIFICATION WHERE CreatedAt < DATE_SUB(CURDATE(), INTERVAL 30 day);, verranno presi tutti gli IOPS, il processo richiederà ore e non sarà possibile inserire molte nuove voci a causa del "Timeout di attesa di blocco superato; provare a riavviare la transazione".

Stavo cercando di descrivere il modo qui: http://mysql.rjweb.org/doc.php/deletebig Tuttavia, sto usando UUID invece di ID di incremento.

Qual è il modo corretto ed efficiente per eliminare quelle righe senza influire sull'inserimento / aggiornamento di nuovi dati?


Hai ragione ypercube, l'ho corretto. Grazie per la segnalazione!
Tianyi Cong,

L'eliminazione di record in blocchi più piccoli, non influisce sull'operazione di inserimento, l'ho provato con il loop e termina l'eliminazione di 70 milioni di record in meno di un'ora rathishkumar.in/2017/12/…
Rathish

Risposte:


11

Crea una tabella temporanea, accendila e spegnila e copia in essa i dati degli ultimi 30 giorni.

#
# Make empty temp table
#
CREATE TABLE NOTIFICATION_NEW LIKE NOTIFICATION;
#
# Switch in new empty temp table
#
RENAME TABLE NOTIFICATION TO NOTIFICATION_OLD,NOTIFICATION_NEW TO NOTIFICATION;
#
# Retrieve last 30 days data 
#
INSERT INTO NOTIFICATION SELECT * FROM NOTIFICATION_OLD
WHERE CreatedAt >= DATE_SUB(CURDATE(), INTERVAL 30 DAY);

Nelle ore di riposo, lascia cadere il vecchio tavolo

DROP TABLE NOTIFICATION_OLD;

Ecco i vantaggi di fare DELETE in questo modo

  1. NOTIFICATION viene svuotato velocemente per mezzo di una tabella vuota.
  2. NOTIFICATION è immediatamente disponibile per i nuovi INSERTI
  3. I restanti 30 giorni vengono aggiunti nuovamente NOTIFICATIONmentre possono verificarsi nuovi INSERT.
  4. Eliminare la vecchia versione di NOTIFICATIONnon interferisce con i nuovi INSERT
  5. NOTA: ho consigliato di fare bait-and-switch per le tabelle DELETE prima di: (Vedi il mio post del 19 luglio 2012: Ottimizzare le query DELETE sulla tabella MEMORY di MySQL )

Provaci !!!


Grazie la risposta Rolando! In che modo MySql gestisce internamente la tabella di rilascio? Prima cancella tutte le colonne e poi rimuovi la tabella o qualcos'altro? Ci vorrà molto meno tempo di eliminare quelle cloumns?
Tianyi Cong,

Sto applicando questa strategia per la gestione temporanea, il comando rename dovrebbe iniziare con "RENAME TABLE"?
Tianyi Cong,

ci sarebbe qualche differenza se lo usassi all'interno di un blocco di transazioni, tenendo presente il timeout di attesa del blocco, avrebbe anche dei contro se il mio tavolo reale fosse davvero enorme, che ora è stato rinominato e deve essere eliminato
Muhammad Omer Aslam,

1
@MuhammadOmerAslam in quel caso, il file ibdata1 (tablespace di sistema) sarebbe cresciuto nei registri di annullamento. Questo è particolarmente vero quando ibdata1 inizia a diventare più grande in dimensione dei file (vedi il mio vecchio post dba.stackexchange.com/questions/40730/… ). È necessario prestare maggiore attenzione utilizzando l'archiviatore pt come indicato nella risposta di Akuzminsky, potrebbe essere limitato per eliminare le righe in blocchi e quindi utilizzare pt-online-schema-change per eseguire ALTER TABLE ENGINE=InnoDB per ridurre la tabella.
RolandoMySQLDBA

1
@MuhammadOmerAslam L'approccio sopra descritto sarebbe perfetto quando hai programmato i tempi di inattività. Seguendo il link nella risposta di akuzminsky ( percona.com/doc/percona-toolkit/LATEST/pt-archiver.html ). È possibile utilizzare pt-archiver per archiviare i dati o semplicemente eliminare i dati senza archiviarli.
RolandoMySQLDBA

3

Il mio preferito è l' archiviatore pt di Percona Toolkit. Si occupa del carico di MySQL, del ritardo di replica.


Grazie la risposta akuzminsky! Lo esaminerò. Provavo Percona quando volevo modificare questa tabella di notifica con pt-online-schema-change. Tuttavia, per apportare la modifica è stato richiesto il privilegio SUPER, che non è fornito da RDS. A proposito, conosci qualche buon modo per modificare un tavolo enorme?
Tianyi Cong,

@TianyiCong hai una nuova domanda: per favore, falla come una nuova domanda e forse commenta qui con un link, non farlo nei commenti non è come funziona questo sito.
Jack dice di provare topanswers.xyz il

-2

crea la tabella notification_temp come seleziona * dalla notifica in cui è stato creato <DATE_SUB (CURDATE (), INTERVAL 30 giorni);

notifica della tabella di rilascio;

RENAME notification_temp A NOTIFICA;


E questo non influirà sui nuovi dati inseriti / aggiornati? Io non la penso così.
Colin 't Hart,

Questo metodo presenta 2 problemi 1) rende NOTIFICATION non disponibile per la durata della DROP TABLE. 2) Gli INSERTI che si verificano durante la CREATE TABLEmancata.
RolandoMySQLDBA,

Un altro problema: dovrebbe direRENAME TABLE notification_temp ...
RolandoMySQLDBA il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.