Die --single-transaction
Option mysqldump
führt eine FLUSH TABLES WITH READ LOCK
Aktion vor dem Starten des Sicherungsjobs durch, jedoch nur unter bestimmten Bedingungen. Eine dieser Bedingungen ist, wenn Sie auch die --master-data
Option angeben .
Im Quellcode aus mysql-5.6.19/client/mysqldump.c
Zeile 5797:
if ((opt_lock_all_tables || opt_master_data ||
(opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
Um eine solide Sperre für die genauen Binlog-Koordinaten zu erhalten, bevor die Transaktion mit wiederholbarem Lesen gestartet wird, --master-data
löst die Option aus, dass diese Sperre abgerufen und dann freigegeben wird, sobald die Binlog-Koordinaten erhalten wurden.
Tatsächlich mysqldump
wird a FLUSH TABLES
gefolgt von a ausgeführt, FLUSH TABLES WITH READ LOCK
da in beiden Fällen die Lesesperre in Fällen, in denen das anfängliche Spülen einige Zeit dauert, schneller erreicht werden kann.
...jedoch...
Sobald es die binlog-Koordinaten erhalten hat, mysqldump
gibt es eine UNLOCK TABLES
Anweisung aus, sodass aufgrund des von Ihnen gestarteten Flushs nichts blockiert werden sollte. Threads sollten auch nicht das Waiting for table flush
Ergebnis der Transaktion sein, die gehalten mysqldump
wird.
Wenn Sie einen Thread im Waiting for table flush
Status sehen, sollte dies bedeuten, dass die FLUSH TABLES [WITH READ LOCK]
Anweisung ausgegeben wurde und zum Zeitpunkt des Starts der Abfrage noch ausgeführt wurde. Daher muss die Abfrage auf das Löschen der Tabelle warten, bevor sie ausgeführt werden kann. Bei der von Ihnen veröffentlichten Prozessliste mysqldump
wird aus derselben Tabelle gelesen, und die Abfrage wurde eine Weile ausgeführt, die blockierenden Abfragen wurden jedoch nicht so lange blockiert.
Dies alles deutet darauf hin, dass etwas anderes passiert ist.
In Bug # 44884 wird ein langjähriges Problem mit der FLUSH TABLES
internen Funktionsweise erläutert . Ich wäre nicht überrascht, wenn das Problem weiterhin besteht. Ich wäre überrascht, wenn dieses Problem jemals "behoben" würde, da es sich um ein sehr komplexes Problem handelt, das in einer Umgebung mit hoher Parallelität praktisch unmöglich zu beheben ist Das Reparieren birgt ein erhebliches Risiko, etwas anderes zu beschädigen oder neues, anderes und immer noch unerwünschtes Verhalten zu erzeugen.
Es ist wahrscheinlich, dass dies die Erklärung für das ist, was Sie sehen.
Speziell:
Wenn eine Abfrage mit langer Laufzeit für eine Tabelle ausgeführt wird und ein Problem auftritt FLUSH TABLES
, FLUSH TABLES
wird die Abfrage blockiert, bis die Abfrage mit langer Laufzeit abgeschlossen ist.
Darüber hinaus werden alle Abfragen, die nach der FLUSH TABLES
Ausgabe beginnen, blockiert, bis die FLUSH TABLES
abgeschlossen ist.
Wenn Sie die FLUSH TABLES
Abfrage beenden, werden die blockierenden Abfragen weiterhin für die ursprüngliche Abfrage mit langer Laufzeit blockiert, die die FLUSH TABLES
Abfrage blockiert hat , da FLUSH TABLES
diese Tabelle (die eine oder Darüber hinaus wird die lange laufende Abfrage noch geleert, und diese anstehende Leerung wird stattfinden, sobald die lang laufende Abfrage abgeschlossen ist - jedoch nicht vorher.
Die wahrscheinliche Schlussfolgerung hier ist, dass ein anderer Prozess - vielleicht ein anderer mysqldump oder eine schlecht beratene Abfrage oder ein schlecht geschriebener Überwachungsprozess - versucht hat, eine Tabelle zu leeren.
Diese Abfrage wurde später durch einen unbekannten Mechanismus beendet oder abgelaufen, aber ihre Nachwirkungen blieben bestehen, bis mysqldump
das Lesen aus der fraglichen Tabelle abgeschlossen war.
Sie können diese Bedingung replizieren, indem Sie versuchen, FLUSH TABLES
während eine lang laufende Abfrage ausgeführt wird. Starten Sie dann eine weitere Abfrage, die blockiert wird. Beenden Sie dann die FLUSH TABLES
Abfrage, wodurch die letzte Abfrage nicht entsperrt wird. Beenden Sie dann die erste Abfrage oder lassen Sie sie beenden, und die letzte Abfrage wird erfolgreich ausgeführt.
Nachträglich hat dies nichts zu tun:
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
Das ist normal, da mysqldump --single-transaction
Probleme a auftreten START TRANSACTION WITH CONSISTENT SNAPSHOT
, die verhindern, dass Daten ausgegeben werden, die während des Speicherauszugs geändert wurden. Ohne das wären die zu Beginn erhaltenen Binlog-Koordinaten bedeutungslos, da das --single-transaction
nicht das wäre, was es behauptet zu sein. Dies sollte in keiner Weise mit dem Waiting for table flush
Problem zusammenhängen, da diese Transaktion offensichtlich keine Sperren enthält.