Von einem Skript aus habe ich tausende Male eine solche Anfrage an meine lokale Datenbank gesendet:
update some_table set some_column = some_value
Ich habe vergessen, den where-Teil hinzuzufügen, daher wurde dieselbe Spalte für alle Zeilen in der Tabelle auf den gleichen Wert gesetzt. Dies wurde tausende Male durchgeführt und die Spalte wurde indiziert, sodass der entsprechende Index wahrscheinlich zu oft aktualisiert wurde .
Ich habe festgestellt, dass etwas nicht stimmt, weil es zu lange gedauert hat, also habe ich das Drehbuch getötet. Ich habe seitdem sogar meinen Computer neu gestartet, aber etwas ist in der Tabelle hängen geblieben, da die Ausführung einfacher Abfragen sehr lange dauert und wenn ich versuche, den entsprechenden Index zu löschen, schlägt dies mit der folgenden Meldung fehl:
Lock wait timeout exceeded; try restarting transaction
Es ist eine innodb-Tabelle, daher ist die Transaktion wahrscheinlich implizit. Wie kann ich diese Tabelle reparieren und die feststeckende Transaktion daraus entfernen?
quelle
SHOW FULL PROCESSLIST
?Antworten:
Ich hatte ein ähnliches Problem und löste es, indem ich die laufenden Threads überprüfte. Verwenden Sie den folgenden Befehl in der MySQL-Befehlszeilenschnittstelle, um die laufenden Threads anzuzeigen:
Es kann auch von phpMyAdmin gesendet werden, wenn Sie keinen Zugriff auf die MySQL-Befehlszeilenschnittstelle haben.
Dadurch wird eine Liste von Threads mit entsprechenden IDs und Ausführungszeit angezeigt, sodass Sie die Threads TÖTEN können, deren Ausführung zu lange dauert. In phpMyAdmin haben Sie eine Schaltfläche zum Stoppen von Threads mithilfe von KILL. Wenn Sie die Befehlszeilenschnittstelle verwenden, verwenden Sie einfach den Befehl KILL gefolgt von der Thread-ID, wie im folgenden Beispiel:
Dadurch wird die Verbindung für den entsprechenden Thread beendet.
quelle
Sie können die aktuell ausgeführten Transaktionen mit überprüfen
Ihre Transaktion sollte eine der ersten sein, da sie die älteste in der Liste ist. Nehmen Sie nun einfach den Wert von
trx_mysql_thread_id
und senden Sie ihm denKILL
Befehl:Wenn Sie sich nicht sicher sind, welche Transaktion Ihnen gehört, wiederholen Sie die erste Abfrage sehr oft und prüfen Sie, welche Transaktionen weiterhin bestehen.
quelle
Überprüfen Sie den InnoDB-Status auf Sperren
Überprüfen Sie die offenen MySQL-Tabellen
Überprüfen Sie ausstehende InnoDB-Transaktionen
Überprüfen Sie die Sperrabhängigkeit - was blockiert was?
Nachdem Sie die obigen Ergebnisse untersucht haben, sollten Sie sehen können, was was sperrt.
Die Hauptursache des Problems könnte auch in Ihrem Code liegen. Überprüfen Sie die zugehörigen Funktionen, insbesondere auf Anmerkungen, wenn Sie JPA wie Hibernate verwenden.
Wie hier beschrieben , kann der Missbrauch der folgenden Anmerkung beispielsweise zu Sperren in der Datenbank führen:
quelle
SELECT * FROM information_schema.innodb_trx t JOIN information_schema.processlist p ON t.trx_mysql_thread_id = p.id
enthüllte den Schuldigen: Der Sperr-Thread kam von meiner On-IP-Adresse ... Ich hatte vergessen, eine Debug-Konsole zu schließen, die ich mitten in einer Transaktion verlassen hatte ...Dies passierte mir, als meine Datenbankgröße zunahm und ich viele Transaktionen damit durchführte.
Die Wahrheit ist, dass es wahrscheinlich eine Möglichkeit gibt, entweder Ihre Abfragen oder Ihre Datenbank zu optimieren, aber versuchen Sie diese beiden Abfragen, um das Problem zu umgehen.
Führen Sie Folgendes aus:
Und dann das:
quelle
Wenn Sie eine Verbindung für eine Transaktion herstellen, erwerben Sie eine Sperre, bevor Sie die Transaktion ausführen. Wenn Sie das Schloss nicht erwerben können, versuchen Sie es für einige Zeit. Wenn die Sperre immer noch nicht verfügbar ist, wird der Fehler "Wartezeit der Sperre überschritten" ausgelöst. Sie können keine Sperre erwerben, weil Sie die Verbindung nicht schließen. Wenn Sie also zum zweiten Mal versuchen, eine Sperre zu erhalten, können Sie die Sperre nicht erwerben, da Ihre vorherige Verbindung immer noch nicht geschlossen ist und die Sperre hält.
Lösung: Schließen Sie die Verbindung oder
setAutoCommit(true)
(gemäß Ihrem Design), um die Sperre aufzuheben.quelle
Starten Sie MySQL neu, es funktioniert einwandfrei.
ABER Vorsicht, wenn eine solche Abfrage nicht funktioniert, liegt irgendwo ein Problem vor:
LIKE %...%
usw.)Wie @syedrakib sagte, funktioniert es, aber dies ist keine langlebige Lösung für die Produktion.
Achtung: Der Neustart kann sich auf Ihre Daten mit inkonsistentem Status auswirken.
Sie können auch überprüfen, wie MySQL Ihre Abfrage mit dem Schlüsselwort EXPLAIN behandelt, und prüfen, ob dort etwas möglich ist, um die Abfrage zu beschleunigen (Indizes, komplexe Tests, ...).
quelle
Gehe zu Prozessen in MySQL.
Ich kann also sehen, dass die Aufgabe noch funktioniert.
Beenden Sie den jeweiligen Prozess oder warten Sie, bis der Prozess abgeschlossen ist.
quelle
Ich bin auf dasselbe Problem mit einer "Update" -Statement gestoßen. Meine Lösung bestand einfach darin, die in phpMyAdmin für die Tabelle verfügbaren Vorgänge durchzugehen. Ich habe den Tisch optimiert, gespült und defragmentiert (nicht in dieser Reihenfolge). Für mich ist es nicht erforderlich, die Tabelle zu löschen und aus dem Backup wiederherzustellen. :) :)
quelle
Ich hatte das gleiche Problem. Ich denke, es war ein Deadlock-Problem mit SQL. Sie können das Schließen des SQL-Prozesses einfach über den Task-Manager erzwingen. Wenn das nicht behoben wurde, starten Sie einfach Ihren Computer neu. Sie müssen die Tabelle nicht löschen und die Daten neu laden.
quelle
Ich hatte dieses Problem beim Versuch, eine bestimmte Gruppe von Datensätzen zu löschen (unter Verwendung von MS Access 2007 mit einer ODBC-Verbindung zu MySQL auf einem Webserver). Normalerweise lösche ich bestimmte Datensätze aus MySQL und ersetze sie dann durch aktualisierte Datensätze (Kaskade lösche mehrere verwandte Datensätze, wodurch das Löschen aller verwandten Datensätze für eine einzelne Datensatzlöschung optimiert wird).
Ich habe versucht, die in phpMyAdmin für die Tabelle verfügbaren Vorgänge (Optimieren, Leeren usw.) durchzugehen, habe jedoch beim Löschen eine erforderliche Berechtigung zum erneuten Laden des Fehlers erhalten. Da sich meine Datenbank auf einem Webserver befindet, konnte ich die Datenbank nicht neu starten. Das Wiederherstellen aus einer Sicherung war keine Option.
Ich habe versucht, eine Löschabfrage für diese Gruppe von Datensätzen auf dem cPanel mySQL-Zugriff im Web auszuführen. Ich habe die gleiche Fehlermeldung erhalten.
Meine Lösung: Ich habe den kostenlosen MySQL-Abfragebrowser von Sun (Oracle) verwendet (den ich zuvor auf meinem Computer installiert habe) und dort die Löschabfrage ausgeführt. Es hat sofort funktioniert, Problem gelöst. Ich konnte dann die Funktion erneut mithilfe des Access-Skripts über die ODBC Access to MySQL-Verbindung ausführen.
quelle
Behoben.
Stellen Sie sicher, dass in der Abfrage kein nicht übereinstimmender Datentyp eingefügt wurde. Ich hatte ein Problem, bei dem ich "Benutzerbrowser-Agentendaten" ausprobierte
VARCHAR(255)
und ein Problem mit dieser Sperre hatte, das jedochTEXT(255)
behoben wurde, als ich sie änderte .Es handelt sich also höchstwahrscheinlich um eine Nichtübereinstimmung des Datentyps.
quelle
Ich habe das Problem gelöst, indem ich die Tabelle gelöscht und aus dem Backup wiederhergestellt habe.
quelle