Vollständiger Prozessdatensatz zur Fehlerbehebung bei MySQL DeadLock

Vollständiger Prozessdatensatz zur Fehlerbehebung bei MySQL DeadLock

【Autor】

Liu Bo: Leitender Datenbankmanager im Ctrip Technical Support Center, mit Schwerpunkt auf Betrieb, Wartung und Fehlerbehebung von SQL Server und MySQL.

【Umfeld】

Versionsnummer: 5.6.21

Isolationsebene: WIEDERHOLBARES LESEN

[Problembeschreibung]

Nach dem Empfang eines Überwachungsalarms meldete die Online-Anwendung DeadLock einen Fehler, der alle 15 Minuten pünktlich angezeigt wurde. Die Fehlerstatistik lautet wie folgt:


Melden Sie sich beim Mysql-Server an, um das Protokoll anzuzeigen:

mysql> Engine-InnoDB-Status anzeigen\G

*** (1) TRANSAKTION:

TRANSAKTION 102973, AKTIV 11 Sek. Start des Indexlesens

MySQL-Tabellen im Einsatz 3, gesperrt 3

LOCK WAIT 4 Sperrstruktur(en), Heap-Größe 1136, 3 Zeilensperren

MySQL-Thread-ID 6, OS-Thread-Handle 140024996574976, Abfrage-ID 83, localhost, US-Aktualisierung

UPDATE TestTable

SETZE Spalte1 = 1,

Spalte2 = sysdate(),

Spalte3 = '026'

Spalte4 = 0

UND Spalte5 = 485

UND Spalte 6 = 'SEK'

*** (1) WARTEN AUF DIE GEWÄHRUNG DIESER SPERRE:

Datensatzsperren Bereichs-ID 417 Seitennummer 1493 n Bits 1000 Index idx_column6 der Tabelle test.TestTable trx ID 102973 Sperrmodus X wartend

Datensatzsperre, Heap Nr. 859 PHYSIKALISCHER DATENSATZ: n_Felder 2; kompaktes Format; Infobits 0

0: Länge 3; Hex 53454b; aufsteigend SEK;;

1: Länge 8; Hex 80000000007e1452; aufsteigend ~ R;;

*** (2) TRANSAKTION:

TRANSAKTION 102972, AKTIV 26 Sek. Start des Indexlesens

MySQL-Tabellen im Einsatz 3, gesperrt 3

219 Sperrstruktur(en), Heapgröße 24784, 2906 Zeilensperre(n), Undo-Logeinträge 7

MySQL-Thread-ID 5, OS-Thread-Handle 140024996841216, Abfrage-ID 84, localhost, US-Aktualisierung

UPDATE TestTable

SETZE Spalte1 = 1,

Spalte2 = sysdate(),

Spalte3 = '026'

Spalte4 = 0

UND Spalte5 = 485

UND Spalte6 = 'SEK'

*** (2) HÄLT DAS SCHLOSS:

Datensatzsperren, Bereichs-ID 417, Seitennummer 1493, n Bits 1000, Index-IDx_Spalte6 der Tabelle test.TestTable, TRX-ID 102972, Sperrmodus X

Datensatzsperre, Heap Nr. 1 PHYSIKALISCHER DATENSATZ: n_Felder 1; kompaktes Format; Infobits 0

0: Länge 8; Hex 73757072656d756d; Asc Supremum;;


Datensatzsperre, Heap Nr. 859 PHYSIKALISCHER DATENSATZ: n_Felder 2; kompaktes Format; Infobits 0

0: Länge 3; Hex 53454b; aufsteigend SEK;;

1: Länge 8; Hex 80000000007e1452; aufsteigend ~ R;;
*** (2) WARTEN AUF DIE GEWÄHRUNG DIESER SPERRE:

Datensatzsperren, Speicherplatz-ID 601, Seitennummer 89642, n Bits 1000, Index-IDx_Spalte6 der Tabelle test.TestTable, TRX-ID 32231892482, Sperrmodus X, Datensätze sperren, aber keine Lückenwartezeit

Datensatzsperre, Heap Nr. 38 PHYSIKALISCHER DATENSATZ: n_Felder 2; kompaktes Format; Infobits 0

0: Länge 3; Hex 53454b; aufsteigend SEK;;

1: Länge 8; Hex 80000000007eea14; aufsteigend ~ ;;

Auf den ersten Blick sollte das Aktualisieren derselben Zeile mit demselben Index ein Block sein und daher einen TimeOut-Fehler melden. Warum wird ein DeadLock-Fehler gemeldet?

[Vorläufige Analyse]

Analysieren wir zunächst (2) TRANSAKTION, TRANSAKTION 32231892482.

Die Informationen zur Wartesperre lauten:

0: Länge 3; Hex 53454b; aufsteigend SEK;;

1: Länge 8; Hex 80000000007eea14; aufsteigend

Die gespeicherten Sperrinformationen lauten:

0: Länge 3; Hex 53454b; aufsteigend SEK;;

1: Länge 8; Hex 80000000007eeac4; aufsteigend

Lassen Sie uns zunächst (1) TRANSAKTION, TRANSAKTION 32231892617 analysieren.

Die Informationen zur Wartesperre lauten:

0: Länge 3; Hex 53454b; aufsteigend SEK;;

1: Länge 8; Hex 80000000007eeac4; aufsteigend

Wir können also eine Deadlock-Tabelle zeichnen, in der zwei Ressourcen voneinander abhängig sind und so einen Deadlock verursachen:

TRANSAKTION Halten Warten
32231892617 53454b\80000000007eea14 53454b\80000000007eeac4
32231892482 53454b\80000000007eeac4 53454b\80000000007eea14

Schauen wir uns das Erläuterungsergebnis noch einmal an:

mysql>desc UPDATE TestTable SET Column1=1, Column2 = sysdate(), Column3 = '025' Column4 = 0 AND Column5 = 477 AND Column6 = 'SEK' \G;

*************************** 1. Reihe ***************************

ID: 1

Auswahltyp: UPDATE

Tabelle: Testtabelle

Partitionen: NULL

Typ: index_merge

mögliche Schlüssel: column5_index,idx_column5_column6_Column1,idxColumn6

Schlüssel: column5_index,idxColumn6

Schlüssellänge: 8,9

Ref: NULL

Reihen: 7

gefiltert: 100,00

Extra: Verwenden von intersect(column5_index,idxColumn6); Verwenden von where

Sie können die Spalte EXTRA sehen:

Verwenden von „intersect(column5_index,idxColumn6)“

Ab 5.1 wurde die Index Merge Optimization-Technologie eingeführt, die die Verwendung mehrerer Indizes ermöglicht, um bedingte Scans derselben Tabelle durchzuführen.

Zugehörige Dokumentation: http://dev.mysql.com/doc/refman/5.7/en/index-merge-optimization.html

Die Index Merge-Methode wird verwendet, um Zeilen mit mehreren Bereichsscans abzurufen und ihre Ergebnisse zu einem zusammenzuführen. Die Zusammenführung kann Vereinigungen, Schnittmengen oder Vereinigungen von Schnittmengen der zugrunde liegenden Scans erzeugen. Diese Zugriffsmethode führt Indexscans aus einer einzelnen Tabelle zusammen; sie führt keine Scans aus mehreren Tabellen zusammen.

【Simulation und Verifizierung】

Basierend auf der obigen vorläufigen Analyse wird spekuliert, dass es durch eine Überschneidung verursacht wird. Daher simulieren und überprüfen wir es in der Testumgebung und öffnen zwei Sitzungen, um einen Deadlock zu simulieren:

Zeitreihen Sitzung1 Sitzung2
1 Beginnen;
2 UPDATE TestTable SET Column2 = sysdate() Column4 = 0 AND Column5 = 47 AND Column6 = 'SEK
Ausführung erfolgreich, betrifft 7 Zeilen
3 Beginnen;
4 UPDATE TestTable SET Column2 = sysdate(), Column4 = 0 AND Column5 = 485 AND Column6 = 'SEK';
Blockiert
5 UPDATE TestTable SET Column2 = sysdate(), Column4 = 0 AND Column5 = 485 AND Column6 = 'SEK';
Erfolgreiche Ausführung
FEHLER 1213 (40001): Beim Versuch, eine Sperre zu erhalten, wurde ein Deadlock festgestellt. Versuchen Sie, die Transaktion neu zu starten.

Basierend auf den obigen Informationen können wir feststellen, dass Sitzung 2 zwar blockiert ist, aber auch einige X-Sperren für die von Sitzung 1 benötigten Ressourcen in Zeitreihe 5 erhalten hat. Wir können eine weitere Abfrage „select count(Column5)“ aus TestTable öffnen, wobei Column5 = 485 ist, SET TRANSACTION ISOLATION LEVEL SERIALIZABLE festlegen, die Zeile mit Column5 = 485 abfragen und die Informationen zur Sperre beobachten:
mysql> AUSWÄHLEN r.trx_id warte_trx_id, r.trx_mysql_thread_id warte_thread, r.trx_query warte_query, b.trx_id

mysql> SELECT r.trx_id warte_trx_id, r.trx_mysql_thread_id warte_thread, r.trx_query warte_abfrage, b.trx_id blockiere_trx_id, b.trx_mysql_thread_id blockiere_thread, b.trx_query blockiere_abfrage FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blockiere_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.anfordernde_trx_id \G;

*************************** 1. Reihe ***************************

wartende_trx_id: 103006

Wartethread: 36

wartende_Abfrage: UPDATE TestTable SET Column1 = 1, Column2 = sysdate(), Column3 = '026' Column4 = 0 AND Column5 = 485 AND Column6 = 'SEK'

Blockierungs-TRX-ID: 103003

blockierender_Thread: 37

Blockierungsabfrage: NULL

*************************** 2. Reihe ***************************

wartende_trx_id: 421500433538672

Wartethread: 39

waiting_query: wähle count(Column5) aus TestTable, wobei Column5 = 485

Blockierungs-TRX-ID: 103006

blockierender_Thread: 36

blockierende_Abfrage: UPDATE TestTable SET Spalte1 = 1, Spalte2 = sysdate(), Spalte3 = '026' Spalte4 = 0 UND Spalte5 = 485 UND Spalte6 = 'SEK'

2 Zeilen im Satz, 1 Warnung (0,00 Sek.)

mysql> wähle * aus information_schema.innodb_lock_waits \G;

*************************** 1. Reihe ***************************

anfordernde_trx_id: 103006

angeforderte Sperr-ID: 103006:417:1493:859

Blockierungs-TRX-ID: 103003

Sperrsperr-ID: 103003:417:1493:859

*************************** 2. Reihe ***************************

anfordernde_trx_id: 421500433538672

angeforderte Sperr-ID: 421500433538672:417:749:2

Blockierungs-TRX-ID: 103006

Sperrsperr-ID: 103006:417:749:2

2 Zeilen im Satz, 1 Warnung (0,00 Sek.)
mysql> wähle * aus INNODB_LOCKS \G;

*************************** 1. Reihe ***************************

Sperr-ID: 103006:417:1493:859

lock_trx_id: 103006

Sperrmodus: X

Sperrtyp: AUFZEICHNUNG

lock_table: test.Testtabelle

lock_index: idxColumn6

Sperrraum: 417

Sperrseite: 1493

lock_rec: 859

lock_data: 'SEK', 8262738

*************************** 2. Reihe ***************************

Sperr-ID: 103003:417:1493:859

lock_trx_id: 103003

Sperrmodus: X

Sperrtyp: AUFZEICHNUNG

lock_table:test.Testtabelle

lock_index: idxColumn6

Sperrraum: 417

Sperrseite: 1493

lock_rec: 859

lock_data: 'SEK', 8262738

*************************** 3. Reihe ***************************

Sperr-ID: 421500433538672:417:749:2

lock_trx_id: 421500433538672

Sperrmodus: S

Sperrtyp: AUFZEICHNUNG

lock_table: test.Testtabelle

lock_index: column5_index

Sperrraum: 417

Sperrseite: 749

lock_rec: 2

Sperrdaten: 485, 8317620

*************************** 4. Reihe ***************************

Sperr-ID: 103006:417:749:2

lock_trx_id: 103006

Sperrmodus: X

Sperrtyp: AUFZEICHNUNG

lock_table: test.Testtabelle

lock_index: column5_index

Sperrraum: 417

Sperrseite: 749

lock_rec: 2

Sperrdaten: 485, 8317620

4 Zeilen im Satz, 1 Warnung (0,00 Sek.)

Es ist ersichtlich, dass Session2, trx_id 103006 trx_id 421500433538672 blockiert hat und trx_id 421500433538672 requested_lock ist auch lock_data: 485, 8317620. Dies zeigt, dass Session2 zwar nicht blockiert ist, aber dennoch die Sperre für den Index column5_index erhält. Der Grund für die Sperrung liegt in der Überschneidung. Die Sperre von idxColumn6 wird ebenfalls benötigt. Jetzt ist die Idee klar. Vereinfachen wir die Informationen zur gesamten Sperrenzuweisung wie in der folgenden Tabelle dargestellt (die angeforderte Sperre ist cyanfarben gekennzeichnet, und die Sperre, die erhalten werden muss, aber nicht erhalten wurde, ist rot gekennzeichnet):

Zeit Sitzung1 Sitzung2
1 477 SEK
2 485 SEK
3 485 SEK Es kommt zu einem Deadlock

Es ist ersichtlich, dass die beiden Ressourcen von 485 SEK eine Schleife bildeten und es schließlich zu einem Deadlock kam.

【Lösung】

  • Am besten ist es, einen gemeinsamen Index für Spalte 5 und Spalte 6 hinzuzufügen.
  • In unserer damaligen Umgebung stellten wir fest, dass der Screening-Grad von Column6 sehr niedrig war, daher löschten wir den Index von Column6.
    Nach dem Löschen des Indexes gegen 10:55 Uhr trat der Fehler nicht mehr auf:

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • MySQL-Fehler: Beim Versuch, eine Sperre zu erhalten, wurde ein Deadlock festgestellt. Versuchen Sie, die Transaktionslösung neu zu starten.
  • Zusammenfassung der Online-Methoden zur Fehlerbehebung bei MySQL-Synchronisierungsfehlern (unbedingt lesen)
  • Eine Lösung für das MySQL-Master-Slave-Synchronisationsproblem
  • Eine langsame MySQL-Abfrage verursachte einen Fehler
  • Super-Deployment-Tutorial zur MHA-Hochverfügbarkeits-Failover-Lösung unter MySQL
  • Übersicht, Installation, Fehlerbehebung, Tipps und Tools zur MySQL-Replikation (geteilt von Huo Ding)
  • Methoden zum Erkennen von MySQL-Tabellenfehlern

<<:  React antd realisiert dynamische Vergrößerung und Verkleinerung der Form

>>:  So stellen Sie ein SpringBoot-Projekt mit Dockerfile bereit

Artikel empfehlen

Beispieloperation MySQL Kurzlink

So richten Sie einen MySQL-Kurzlink ein 1. Überpr...

Tutorial zur Installation von Pycharm und Ipython unter Ubuntu 16.04/18.04

Unter Ubuntu 18.04 1. sudo apt install python ins...

So verwenden Sie residente Knoten für die Ebenenverwaltung in CocosCreator

CocosCreator-Version: 2.3.4 Die meisten Spiele ve...

So konfigurieren Sie den Tomcat-Server für Eclipse und IDEA

Tomcat-Serverkonfiguration Jeder, der das Web ken...

JavaScript-Implementierung des klassischen Schlangenspiels

In diesem Artikel wird der spezifische JavaScript...

Detaillierte Erläuterung der Wissenspunkte zu Linux Netfilter/Iptables

Netzfilter Netfilter ist ein Paketverarbeitungsmo...

JavaScript zum Erzielen eines Dropdown-Menüeffekts

Verwenden Sie Javascript, um ein Dropdown-Menü zu...

Auszeichnungssprache - für

Klicken Sie hier, um zum Abschnitt „HTML-Tutorial“...

Anwendung von HTML und CSS in Flash

Anwendung von HTML und CSS in Flash: Ich habe zufä...

MySQL-Variablenprinzipien und Anwendungsbeispiele

In der MySQL-Dokumentation können MySQL-Variablen...