Analyse von MySQL-Lock-Wait- und Deadlock-Problemen

Analyse von MySQL-Lock-Wait- und Deadlock-Problemen

Vorwort:

Beim Betrieb und der Wartung von MySQL verursachen Warte- und Deadlock-Probleme große Kopfschmerzen für Datenbankadministratoren und Entwickler. Solche Probleme können zu Geschäftsrückschlägen, Einfrieren und anderen Ausfällen führen. Insbesondere bei stark ausgelasteten Systemen sind die Auswirkungen bei Deadlocks schwerwiegender. In diesem Artikel erfahren Sie, was Lock-Waiting und Deadlocks sind und wie Sie solche Probleme analysieren und beheben.

1. Verstehen Sie Lock Waiting und Deadlock

Der Grund für das Warten auf eine Sperre oder einen Deadlock ist, dass der Zugriff auf die Datenbank eine Sperre erfordert. Dann fragen Sie sich vielleicht, warum wir eine Sperre benötigen? Der Grund besteht darin, die Datenkorrektheit in gleichzeitigen Aktualisierungsszenarien sicherzustellen und die Isolierung von Datenbanktransaktionen sicherzustellen.

Stellen Sie sich ein Szenario vor, in dem Sie ein Buch mit dem Titel „High Performance MySQL“ aus der Bibliothek ausleihen möchten. Um zu verhindern, dass jemand das Buch im Voraus ausleiht, können Sie es im Voraus reservieren (sperren). Wie können Sie diese Sperre hinzufügen?

  • Sperrbibliothek (Sperren auf Datenbankebene)
  • Sperren aller datenbankbezogenen Bücher (Sperren auf Tabellenebene)
  • Nur MySQL-bezogene Bücher sperren (Sperre auf Seitenebene)
  • Nur das Buch „High Performance MySQL“ sperren (Zeilensperre)

Je feiner die Sperrgranularität, desto höher der Parallelitätsgrad und desto komplexer die Implementierung.

Das Warten auf eine Sperre kann auch als Warten auf eine Transaktion bezeichnet werden. Die später ausgeführte Transaktion wartet darauf, dass die zuvor verarbeitete Transaktion die Sperre freigibt. Wenn die Wartezeit jedoch die MySQL-Sperrwartezeit überschreitet, wird diese Ausnahme ausgelöst. Die Fehlermeldung nach dem Wartezeitlimit lautet „Wartezeitlimit für Sperre überschritten …“.

Ein Deadlock tritt auf, wenn zwei Transaktionen darauf warten, dass die jeweils andere Transaktion die Sperre für dieselbe Ressource freigibt, was zu einer Endlosschleife führt. Wenn ein Deadlock auftritt, wird sofort die Fehlermeldung „Beim Versuch, die Sperre zu erhalten, wurde ein Deadlock gefunden …“ gemeldet.

2. Wiederauftreten und Behandlung des Phänomens

Nehmen wir MySQL 5.7.23 als Beispiel (Isolationsebene ist RR), um die beiden oben genannten abnormalen Phänomene zu reproduzieren.

mysql> anzeigen, erstellen, Tabelle test_tb\G
*************************** 1. Reihe ***************************
       Tabelle: test_tb
Tabelle erstellen: CREATE TABLE `test_tb` (
  `id` int(11) NICHT NULL AUTO_INCREMENT,
  `col1` varchar(50) NICHT NULL STANDARD '',
  `col2` int(11) NICHT NULL STANDARD '1',
  `col3` varchar(20) NICHT NULL STANDARD '',
  Primärschlüssel (`id`),
  SCHLÜSSEL `idx_col1` (`col1`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1 Zeile im Satz (0,00 Sek.)

mysql> wähle * aus test_tb;
+----+------+------+------+
| ID | Spalte1 | Spalte2 | Spalte3 |
+----+------+------+------+
| 1 | fdg | 1 | abc |
| 2 | ein | 2 | fg |
| 3 | ghrv | 2 | rhdv |
+----+------+------+------+
3 Zeilen im Satz (0,00 Sek.)

# Transaktion 1 wird zuerst ausgeführt mysql> begin;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

mysql> wähle * aus test_tb, wobei col1 = „a“ für Update;
+----+------+------+------+
| ID | Spalte1 | Spalte2 | Spalte3 |
+----+------+------+------+
| 2 | ein | 2 | fg |
+----+------+------+------+
1 Zeile im Satz (0,00 Sek.)

# Transaktion 2 und dann mysql ausführen> begin;
Abfrage OK, 0 Zeilen betroffen (0,01 Sek.)

mysql> aktualisiere test_tb, setze col2 = 1, wobei col1 = „a“;
FEHLER 1205 (HY000): Wartezeit für Sperre überschritten; versuchen Sie, die Transaktion neu zu starten.

Der Grund für die obige Ausnahme liegt darin, dass Transaktion 2 auf die Zeilensperre von Transaktion 1 wartet, Transaktion 1 jedoch nicht festgeschrieben wurde und das Wartezeitlimit zu einem Fehler führt. Das Wartezeitlimit für die InnoDB-Zeilensperre wird durch den Parameter innodb_lock_wait_timeout gesteuert. Der Standardwert dieses Parameters beträgt 50 Sekunden. Das bedeutet, dass Transaktion 2 standardmäßig 50 Sekunden wartet. Wenn die Zeilensperre immer noch nicht erreicht wird, wird eine Wartezeitüberschreitungsausnahme gemeldet und die Anweisung wird zurückgesetzt.

Bei Version 5.7 können wir beim Auftreten einer Wartezeit zwischen den Sperren mehrere Systemtabellen im Informationsschema anzeigen, um den Transaktionsstatus abzufragen.

  • innodb_trx Alle aktuell laufenden Transaktionen.
  • innodb_locks Die aktuell auftretenden Sperren.
  • innodb_lock_waits Sperre Wartekorrespondenz
# Wenn eine Sperrwartezeit auftritt, können Sie alle Transaktionen in der Tabelle innodb_trx anzeigen.
 # Wenn der trx_state-Wert LOCK WAIT ist, bedeutet dies, dass sich die Transaktion im Wartezustand befindet. mysql> select * from information_schema.innodb_trx\G
*************************** 1. Reihe ***************************
                    trx_id: 38511
                 trx_state: SPERRE WARTEN
               trx_started: 2021-03-24 17:20:43
     trx_requested_lock_id: 38511:156:4:2
          trx_wait_started: 24.03.2021 17:20:43
                trx_gewicht: 2
       trx_mysql_thread_id: 1668447
                 trx_query: Aktualisiere test_tb, setze col2 = 1, wobei col1 = „a“
       trx_operation_state: Indexlesen wird gestartet
         trx_tables_in_use: 1
         trx_tables_locked: 1
          Anzahl der Lockstrukturen: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 1
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: WIEDERHOLBARES LESEN
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_ist_schreibgeschützt: 0
trx_autocommit_non_locking: 0
*************************** 2. Reihe ***************************
                    trx_id: 38510
                 trx_state: LÄUFT
               trx_started: 2021-03-24 17:18:54
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_gewicht: 4
       trx_mysql_thread_id: 1667530
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 1
          Anzahl der Lockstrukturen: 4
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 3
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: WIEDERHOLBARES LESEN
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_ist_schreibgeschützt: 0
trx_autocommit_non_locking: 0
2 Zeilen im Satz (0,00 Sek.)

# Bedeutung des Feldwerts innodb_trx trx_id: Transaktions-ID.
trx_state: Transaktionsstatus, der die folgenden Zustände umfasst: RUNNING, LOCK WAIT, ROLLING BACK und COMMITTING.
trx_started: Startzeit der Transaktion.
trx_requested_lock_id: Die ID der Transaktion, die derzeit auf die Sperre wartet. Sie können mit der Tabelle INNODB_LOCKS JOIN durchführen, um detailliertere Informationen zu erhalten.
trx_wait_started: Die Zeit, zu der die Transaktion mit dem Warten beginnt.
trx_weight: Das Gewicht der Transaktion.
trx_mysql_thread_id: Transaktions-Thread-ID, die mit der PROCESSLIST-Tabelle verknüpft werden kann.
trx_query: Die von der Transaktion ausgeführte SQL-Anweisung.
trx_operation_state: aktueller Betriebsstatus der Transaktion.
trx_tables_in_use: Die Anzahl der Tabellen, die im von der aktuellen Transaktion ausgeführten SQL verwendet werden.
trx_tables_locked: Die Anzahl der Zeilensperren, die aktuell SQL ausführen.
trx_lock_structs: Die Anzahl der von der Transaktion beibehaltenen Sperren.
trx_isolation_level: Die Isolationsstufe der aktuellen Transaktion.

# Die Ansicht sys.innodb_lock_waits zeigt auch den Wartestatus der Transaktion an und gibt das SQL zum Beenden der Verbindung aus
mysql> wähle * aus sys.innodb_lock_waits\G
*************************** 1. Reihe ***************************
                wait_started: 24.03.2021 17:20:43
                    Wartezeit: 00:00:22
               Wartezeit in Sekunden: 22
                gesperrte_Tabelle: `testdb`.`test_tb`
                gesperrter_index: idx_col1
                 gesperrter Typ: AUFZEICHNUNG
              wartende_trx_id: 38511
         waiting_trx_started: 24.03.2021 17:20:43
             Wartezeit: 00:00:22
     waiting_trx_rows_locked: 1
   waiting_trx_rows_modified: 0
                 warte_pid: 1668447
               waiting_query: Aktualisiere test_tb, setze col2 = 1, wobei col1 = „a“
             Wartesperren-ID: 38511:156:4:2
           Wartesperrmodus: X
             Blockierungs-TRX-ID: 38510
                Blockierungs-PID: 1667530
              Blockierungsabfrage: NULL
            Sperrsperr-ID: 38510:156:4:2
          Blockierungssperrmodus: X
        blocking_trx_started: 24.03.2021 17:18:54
            Blockierung_TRX_Alter: 00:02:11
    Blockierung_TRX_Zeilen_gesperrt: 3
  Blockieren von TRX-Zeilen geändert: 0
     sql_kill_blocking_query: KILL-ABFRAGE 1667530
sql_kill_blocking_connection: KILL 1667530

Die Ansicht sys.innodb_lock_waits konsolidiert den Wartestatus von Transaktionen und bietet eine Kill-Anweisung, um die Quelle der Blockierung zu beseitigen. Allerdings bedarf die Entscheidung, die Verbindung zu trennen, noch einer umfassenden Überlegung.

Deadlock unterscheidet sich geringfügig vom Warten auf eine Sperre. Lassen Sie uns auch einfach das Deadlock-Phänomen reproduzieren.

# Zwei Transaktionen öffnen # Transaktion 1 wird ausgeführt mysql> update test_tb set col2 = 1 where col1 = 'a';
Abfrage OK, 1 Zeile betroffen (0,00 Sek.)
Übereinstimmende Zeilen: 1 Geändert: 1 Warnungen: 0

# Transaktion 2 mysql> update test_tb set col2 = 1 wobei id = 3;
Abfrage OK, 1 Zeile betroffen (0,00 Sek.)
Übereinstimmende Zeilen: 1 Geändert: 1 Warnungen: 0

# Kehren Sie zu Transaktion 1 zurück und drücken Sie die Eingabetaste. Diese Anweisung befindet sich im Sperrwartezustand. mysql> update test_tb set col1 = 'abcd' where id = 3;
Abfrage OK, 1 Zeile betroffen (5,71 Sek.)
Übereinstimmende Zeilen: 1 Geändert: 1 Warnungen: 0

# Kehren Sie zu Transaktion 2 zurück und führen Sie sie erneut aus. Zu diesem Zeitpunkt warten die beiden aufeinander und es tritt ein Deadlock auf. mysql> update test_tb set col3 = 'gddx' where col1 = 'a';
FEHLER 1213 (40001): Beim Versuch, eine Sperre zu erhalten, wurde ein Deadlock festgestellt. Versuchen Sie, die Transaktion neu zu starten.

Nach dem Auftreten eines Deadlocks wird eine Transaktion zum Rollback ausgewählt. Um die Ursache des Deadlocks herauszufinden, können Sie „show engine innodb status“ ausführen, um das Deadlock-Protokoll anzuzeigen. Basierend auf dem Deadlock-Protokoll und der Geschäftslogik können Sie die Ursache des Deadlocks weiter lokalisieren.

In praktischen Anwendungen sollten wir versuchen, Deadlocks zu vermeiden. Wir können von den folgenden Aspekten ausgehen:

  • Halten Sie die Transaktionen so klein wie möglich und packen Sie keine komplexe Logik in eine einzige Transaktion.
  • Wenn mehrere Datensatzzeilen beteiligt sind, sind unterschiedliche Transaktionen erforderlich, um in der gleichen Reihenfolge auf sie zuzugreifen.
  • Durch rechtzeitiges Festschreiben oder Zurücksetzen von Transaktionen kann die Wahrscheinlichkeit eines Deadlocks verringert werden.
  • Die Tabelle muss über entsprechende Indizes verfügen.
  • Sie können versuchen, die Isolationsebene auf RC zu ändern.

Zusammenfassen:

In diesem Artikel werden kurz die Ursachen für das Warten auf Sperren und Deadlocks vorgestellt. Tatsächlich ist es im realen Geschäft immer noch schwierig, Deadlocks zu analysieren, was eine gewisse Erfahrung erfordert. Dieser Artikel richtet sich nur an Anfänger und ich hoffe, Sie können sich einen ersten Eindruck vom Deadlock verschaffen.

Oben finden Sie eine detaillierte Analyse der MySQL-Lock-Wait- und Deadlock-Probleme. Weitere Informationen zu MySQL-Lock-Wait- und Deadlock-Problemen finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Erfahren Sie in einem Artikel mehr über die absichtliche gemeinsame Sperre, die absichtliche exklusive Sperre und den Deadlock in MySQL
  • Implementierung von Zeilensperre, Tabellensperre und Deadlock des MySQL-Sperrmechanismus
  • Ali-Interview: Handhabung von MySQL-Deadlock-Problemen
  • Lösung für das MySQL-Deadlock-Problem auf RC-Ebene
  • So drucken Sie das Deadlock-Protokoll in MySQL
  • Detaillierte Erläuterung von MySQL-Deadlocks sowie Datenbank- und Tabellen-Sharding-Problemen
  • MySQL Online-Übung zur Deadlock-Analyse
  • Mysql super detaillierte Erklärung des Deadlock-Problems

<<:  Shtml Kurzanleitung

>>:  Reines CSS3 zum Erstellen eines Beispielcodes für Seitenwechseleffekte

Artikel empfehlen

Navicat-Remoteverbindung zur MySQL-Implementierungsschritteanalyse

Vorwort Ich glaube, dass jeder auf einem Remote-S...

Implementierung eines einfachen Gobang-Spiels mit nativem JavaScript

In diesem Artikel finden Sie den spezifischen Cod...

Details zur React Routing Link-Konfiguration

1. Link zum Attribut (1) Platzieren Sie den Routi...

Nginx verwendet den Gzip-Algorithmus zum Komprimieren von Nachrichten

Was ist HTTP-Komprimierung Manchmal werden relati...

Lösung für die Nginx-Installation ohne Generierung des sbin-Verzeichnisses

Fehlerbeschreibung: 1. Nach der Installation von ...

Eine kurze Diskussion zum Problem des Docker-Run-Containers im erstellten Status

Bei einem aktuellen Problem gibt es folgendes Phä...

Wichtige Hinweise zu PHP-HTMLhtml-Wissenspunkten (unbedingt lesen)

1. Verwenden Sie Frameset, Frame und Iframe, um m...

Was ist ZFS? Gründe für die Verwendung von ZFS und seine Funktionen

Geschichte von ZFS Das Z-Dateisystem (ZFS) wurde ...

Webdesign-Erfahrung: Das Navigationssystem schlank machen

<br />Bei Diskussionen mit meinen Freunden h...

Implementierungsbeispiel zum Schließen der Browserabmeldung in Vue

Inhaltsverzeichnis 1. beforeunload-Ereignis 2. Er...

el-table in vue realisiert automatischen Deckeneffekt (unterstützt feste)

Inhaltsverzeichnis Vorwort Umsetzungsideen Wirkun...