Interner Grund für den Tötungsprozess, der in MySQL viel Zeit in Anspruch nimmt


7

Ich habe die Struktur einer großen Tabelle mit kopiert (es ist übrigens eine InnoDB- Tabelle).

CREATE TABLE tempTbl LIKE realTbl 

Dann habe ich einen Index geändert und ihn ausgefüllt, damit ich einen Test durchführen kann. Das Befüllen erfolgte mit:

INSERT INTO  `tmpTbl` 
SELECT *
FROM `realTbl`

Das hat zu lange gedauert, deshalb wollte ich diesen Test beenden. 1

Ich habe den Prozess abgebrochen, während er sich im Status "Daten senden" befand: Er ist jetzt "beendet" und befindet sich immer noch im Status "Daten senden".

Ich weiß, dass einige abgebrochene Prozesse Änderungen rückgängig machen müssen und daher (gleichermaßen?) Lange dauern können, um beendet zu werden, verglichen mit der Dauer, in der sie ausgeführt wurden, aber ich kann mir nicht vorstellen, warum dies jetzt der Fall ist: Die gesamte Tabelle muss geleert werden.

Ich bin gespannt, was passiert, wenn eine einfache Abfrage wie diese sehr lange gestoppt / beendet werden muss. Um Ihnen einige Zahlen zu geben: Der Einsatz lief eine oder drei Stunden, der Kill ist jetzt näher an 5 7. Es sieht fast so aus, als würde es DELETEfür jedes INSERTMal ausgeführt, und das Löschen dauert länger als das Einfügen? Wäre das überhaupt logisch?

(Und wenn jemand weiß, wie man meinen Testserver wieder in Form bringt, wäre das auch schön, da er einige Ressourcen verbraucht, aber das ist im Moment nicht wirklich wichtig :))


1) Ich weiß noch nicht warum (es ist eine große Tabelle, 10 Millionen Zeilen, aber es sollte so lange dauern?), Aber das ist eine andere Sache / nicht Teil dieser Frage :). Es könnte sein, dass mein Test klüger oder schneller hätte sein können, aber das ist jetzt auch nicht die Frage: D.


1
Wie stehen die Chancen, dass ich nach der Antwort auf dieselbe Frage suche? : o
Graham

Antworten:


11

Der Grund, warum der Kill so lange dauert, ist höchstwahrscheinlich auf die durch die innodb-Transaktion ausgegebenen Rollbacks zurückzuführen. Von InnoDB-Leistungstipps :

Vorsicht vor großen Rollbacks von Masseneinfügungen: InnoDB verwendet den Einfügepuffer, um Festplatten-E / A in Einfügungen zu speichern, aber bei einem entsprechenden Rollback wird kein solcher Mechanismus verwendet. Ein festplattengebundenes Rollback kann 30-mal so lange dauern wie das entsprechende Einfügen. Das Beenden des Datenbankprozesses hilft nicht, da das Rollback beim Serverstart erneut gestartet wird.

Bearbeiten: Die Innodb Force Recovery- Methoden könnten für Sie von Nutzen sein (ich bin froh, dass Sie dies in einer Testumgebung getan haben).

Sie können den mysqld-Prozess beenden und innodb_force_recovery auf 3 setzen, um die Datenbank ohne Rollback aufzurufen. Anschließend können Sie die Tabelle, die den außer Kontrolle geratenen Rollback verursacht, fallen lassen.

Fügen Sie beim nächsten Mal jedes Mal eine kleine Teilmenge der Daten ein. Das Einfügen von 10 Millionen Zeilen sollte nicht so lange dauern, aber es kann mehrere Gründe dafür geben. Ohne Ihre Umgebung zu kennen, kann ich Ihnen keine Ratschläge geben.


Kurzum: Ich bin gefickt ... Bin ich froh, dass dies eine Testumgebung ist ...
Nanne

@nanne fügte ein wenig hinzu, wie man die Wiederherstellung erzwingt. Ich bin froh, dass es sich um eine Testumgebung handelt!
Derek Downey

Ich habe gerade auch dieses Zitat gefunden, ich werde es versuchen. @ Einfügung: Sie haben Recht: Es kam mir nicht einmal in den Sinn, es könnte so lange dauern, also habe ich nie über Alternativen nachgedacht :)
Nanne

@Nanne von oben, ich würde sagen, deine innodb_buffer_pool_sizeist zu niedrig. Weitere Optionen finden Sie im Abschnitt "Datenträger-E / A" des Leistungstipps.
Derek Downey

Ich werde das überprüfen, danke. Wie auch immer, die Wiederherstellung nach Tötung und Gewalt scheint funktioniert zu haben, obwohl ich den Prozess nicht stoppen konnte. Am Ende habe ich einfach etwas getan kill -9, um damit fertig zu werden.
Nanne

2

Ich kann darin eine unordentliche Operation sehen. Das tmpTbl ist InnoDB. Das Laden neuer Daten führt zu MVCC- Aktivitäten. Dadurch werden Änderungen in den Redo-Protokollen gestapelt (in ib_logfile0 und ib_logfile1 enthalten, möglicherweise auch in ibdata1).

Sobald Sie INSERT beendet haben, müssen alle Änderungen (für jede Zeile ein neuer Datensatz anstelle eines Datensatzes) an der InnoDB-Tabelle zurückgesetzt werden.

Sie könnten mysqld wahrscheinlich töten und mysqld erneut starten, um während der Crash-Wiederherstellungsphase des MySQL-Starts auf etwas davon zu stoßen.


Ich glaube, ich verstehe, aber was meinst du mit diesem letzten Satz? Dass, wenn ich das Ding töte, die Wiederherstellungsphase den "Rollback" von vorne beginnen könnte? Das wäre nicht gut. Ich lasse es jetzt nur laufen, aber es nähert sich jetzt 7 Stunden Laufzeit, was lächerlich wird. Würden Sie für oder gegen das Töten des Mysqld raten?
Nanne

Ja, du hast es verstanden. Was den letzten Satz betrifft, erklärt @DTest es etwas mehr.
RolandoMySQLDBA
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.