Massenlöschung für große Tabelle in MySQL

9

Ich habe eine Benachrichtigungstabelle, die ungefähr 100 Millionen Zeilen enthält, die in Amazon RDS mit 1000 IOPS gehostet werden, und ich möchte diese Zeilen löschen, die älter als ein Monat sind.

In DELETE FROM NOTIFICATION WHERE CreatedAt < DATE_SUB(CURDATE(), INTERVAL 30 day);diesem Fall werden alle IOPS ausgeführt, der Vorgang dauert Stunden, und viele neue Einträge können nicht eingefügt werden, da "Wartezeit für Sperren überschritten wurde. Versuchen Sie, die Transaktion neu zu starten".

Ich habe versucht, die hier beschriebene Vorgehensweise zu verwenden: http://mysql.rjweb.org/doc.php/deletebig Ich verwende jedoch die UUID anstelle der Inkrement-ID.

Was ist der richtige und effiziente Weg, um diese Zeilen zu löschen, ohne dass das Einfügen / Aktualisieren neuer Daten beeinträchtigt wird?

Tianyi Cong
quelle
Du bist richtig ypercube, ich habe es korrigiert. Vielen Dank für den Hinweis!
Tianyi Cong
Das Löschen von Datensätzen in kleineren Blöcken hat keinen Einfluss auf den Einfügevorgang. Ich habe es mit einer Schleife versucht und das Löschen von 70 Millionen Datensätzen
Rathish

Antworten:

10

Erstellen Sie eine temporäre Tabelle, schalten Sie sie ein und aus und kopieren Sie die Daten der letzten 30 Tage hinein.

#
# 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);

Lassen Sie in Ihrer Freizeit den alten Tisch fallen

DROP TABLE NOTIFICATION_OLD;

Hier sind die Vorteile solcher DELETEs

  1. NOTIFICATION wird durch Umschalten in eine leere Tabelle schnell geleert.
  2. NOTIFICATION ist ab sofort für neue INSERTs verfügbar
  3. Die verbleibenden 30 Tage werden wieder hinzugefügt, NOTIFICATIONwährend neue INSERTs stattfinden können.
  4. Das NOTIFICATIONLöschen der alten Version von beeinträchtigt neue INSERTs nicht
  5. HINWEIS: Ich habe empfohlen, Bait-and-Switch für Tabelle DELETEs durchzuführen, bevor: (Siehe meinen Beitrag vom 19. Juli 2012: Optimieren der DELETE-Abfrage in der MySQL MEMORY-Tabelle )

Versuche es !!!

RolandoMySQLDBA
quelle
Danke die Antwort Rolando! Wie geht MySQL intern mit Drop-Tabellen um? Zuerst alle Spalten löschen, dann Tabelle oder etwas anderes entfernen? Wird es viel kürzer dauern, als diese Spalten zu löschen?
Tianyi Cong
Ich wende diese Strategie auf das Staging an. Sollte der Befehl zum Umbenennen mit "RENAME TABLE" beginnen?
Tianyi Cong
3

Mein Favorit ist pt-archiver von Percona Toolkit. Es kümmert sich um MySQL-Last, Replikationsverzögerung.

akuzminsky
quelle
Danke die Antwort akuzminsky! Ich werde es mir ansehen. Ich habe Percona ausprobiert, als ich diese Benachrichtigungstabelle mit pt-online-schema-change ändern wollte. Für die Änderung war jedoch das SUPER-Privileg erforderlich, das nicht von RDS bereitgestellt wird. Übrigens, kennen Sie einen guten Weg, um einen großen Tisch zu verändern?
Tianyi Cong
@TianyiCong Sie haben eine neue Frage: Bitte stellen Sie sie als neue Frage und kommentieren Sie sie hier möglicherweise mit einem Link. Fragen Sie sie nicht in Kommentaren, so funktioniert diese Website nicht.
Jack sagt, versuchen Sie es mit topanswers.xyz
-2

Erstellen Sie die Tabelle notification_temp als select * aus Benachrichtigung, wobei CreatedAt <DATE_SUB (CURDATE (), INTERVAL 30 Tage);

Drop-Table-Benachrichtigung;

RENAME notification_temp TO NOTIFICATION;

user52557
quelle
Und dies hat keine Auswirkungen auf das Einfügen / Aktualisieren neuer Daten? Das glaube ich nicht.
Colin 't Hart
Diese Methode hat 2 Probleme 1) macht NOTIFICATION für die Dauer der DROP TABLE nicht verfügbar. 2) INSERTs, die während der auftreten, CREATE TABLEwerden übersehen.
RolandoMySQLDBA
Ein weiteres Problem: Es sollte RENAME TABLE notification_temp ...
heißen