Löschen der MySQL-Tabelle mit ausstehenden Transaktionen

10

Gibt es eine Möglichkeit, eine InnoDB-Tabelle oder -Datenbank mit ausstehenden Transaktionen in MySQL zu löschen (vorzugsweise auf Dateisystemebene)?

Was ist passiert:

Ich verwende MySQL 5.5.28 und habe ausgeführt LOAD DATA INFILE…, um einen großen Datensatz ( 300 Millionen Zeilen) in eine InnoDB-Tabelle zu importieren. Ich habe vorher nicht benutzt set autocommit = 0;. Leider mysqldwurde mitten im Import gestoppt.

Beim Neustart mysqlwird versucht, die Transaktion zurückzusetzen, die das Systemprotokoll mit folgenden Meldungen füllt:

mysqld_safe [4433]: 121212 16:58:52 InnoDB: Warten auf den Abschluss einer aktiven Transaktion

Das Problem ist, dass das Rollback jetzt länger als 25 Stunden mysqldläuft und keine Socket-Verbindungen akzeptiert werden.

Ich kann nicht einfach löschen /var/lib/mysql/*und von vorne beginnen, da sich auf diesem Computer auch einige andere InnoDB-Datenbanken / -Tabellen befinden. Die problematische Tabelle ist jedoch die einzige Tabelle in einer separaten Datenbank. Das Löschen der gesamten Tabelle oder der gesamten Datenbank ist kein Problem, da ich anschließend alle Daten erneut importieren kann.

dasup
quelle

Antworten:

8

Es gibt nichts, was Sie wirklich tun können, da ein Rollback über den UNDO-Tabellenbereich in ibdata1 durchgeführt wird , der immens hätte wachsen müssen.

Wenn Sie den mysqld-Prozess beenden und mysql neu starten, wird es nur dort fortgesetzt, wo es im Rahmen des Absturzwiederherstellungszyklus aufgehört hat.

HAFTUNGSAUSSCHLUSS: Nicht verantwortlich für Datenverlust

Was Sie tun könnten, könnte zu Datenverlust für andere Tabellen führen, aber Sie können etwas tun, um den normalen Crash-Wiederherstellungszyklus von InnoDB zu umgehen.

Es gibt eine Startoption namens innodb_force_recovery , mit der Sie verschiedene Phasen der InnoDB- Absturzwiederherstellung umgehen können.

Laut MySQL-Dokumentation zum Erzwingen der Wiederherstellung von InnoDB sind hier die Einstellungen und ihre Auswirkungen aufgeführt:

1 (SRV_FORCE_IGNORE_CORRUPT)

Lassen Sie den Server auch dann laufen, wenn er eine beschädigte Seite erkennt. Versuchen Sie, SELECT * FROM tbl_name über beschädigte Indexdatensätze und -seiten springen zu lassen, was beim Speichern von Tabellen hilfreich ist.

2 (SRV_FORCE_NO_BACKGROUND)

Verhindern Sie, dass der Master-Thread ausgeführt wird. Wenn während des Löschvorgangs ein Absturz auftreten würde, verhindert dieser Wiederherstellungswert dies.

3 (SRV_FORCE_NO_TRX_UNDO)

Führen Sie nach der Wiederherstellung nach einem Absturz keine Transaktions-Rollbacks aus.

4 (SRV_FORCE_NO_IBUF_MERGE)

Verhindern Sie Zusammenführungsvorgänge für Einfügepuffer. Wenn sie einen Absturz verursachen würden, tun Sie sie nicht. Berechnen Sie keine Tabellenstatistiken.

5 (SRV_FORCE_NO_UNDO_LOG_SCAN)

Sehen Sie sich beim Starten der Datenbank keine Rückgängig-Protokolle an: InnoDB behandelt auch unvollständige Transaktionen als festgeschrieben.

6 (SRV_FORCE_NO_LOG_REDO)

Führen Sie das Redo-Log-Roll-Forward im Zusammenhang mit der Wiederherstellung nicht durch.

Mit Transaktionsänderungen, die in den UNDO- und REDO-Protokollen vergraben sind, laufen Sie Gefahr

  • Datenverlust, der geschrieben werden soll
  • Daten behalten, die gelöscht werden sollen

Wenn Sie schlimme Nebenwirkungen erwarten, sichern Sie die gesamte Datei / var / lib / mysql und platzieren Sie sie an einem Ort, falls Sie ibdata1, ib_logfile0 und ib_logfile1 kopieren und die normale Wiederherstellung wiederholen möchten.

Wenn MySQL in einem der Modi vollständig aktiv ist

  • mysqldump alle Daten außer der beleidigenden Tabelle
  • Herunterfahren MySQL
  • Entfernen Sie alles in / var / lib / mysql außer / var / lib / mysql / mysql
  • starte mysql
  • Laden Sie den mysqldump neu

CAVEAT: Stellen Sie sicher, dass Sie alles sichern !!!

Ich hoffe das hilft !!!

RolandoMySQLDBA
quelle
1

Ich hatte diese Woche eine ähnliche Situation.

Und nach vier Iterationen, in denen eine vollständige Sicherung auf einem Testserver wiederhergestellt und versucht wurde, die Tabellen mit den riesigen ausstehenden Transaktionen zu löschen, zu löschen oder zu beenden, kamen wir schließlich zum Freitagnachmittag und beschlossen, sie einfach laufen zu lassen. Innerhalb von drei Tagen wurde die Transaktion mit einer vernachlässigbaren Serverlast abgeschlossen und die Datenbank war in Ordnung. Das war viel besser als alle manuellen Operationen an .frm-Dateien und MySQL-Tabellen, die versucht hatten und fehlgeschlagen waren.

Meine Lösung: Löschen Sie es nicht . Lassen Sie die ausstehenden Transaktionen zu, auch wenn Sie andere Vorgänge für einige Tage verschieben müssen, oder suchen Sie irgendwo Speicherplatz oder lassen Sie Ihren Slave-Server die Last übernehmen.

Andrew Lorien
quelle