MySQL-Deadlock-Routine: inkonsistente Batch-Einfügereihenfolge unter eindeutigem Index

MySQL-Deadlock-Routine: inkonsistente Batch-Einfügereihenfolge unter eindeutigem Index

Vorwort

Das Wesen eines Deadlocks ist Ressourcenwettbewerb. Wenn die Reihenfolge der Batcheinfügung inkonsistent ist, kann dies leicht zu einem Deadlock führen. Lassen Sie uns diese Situation analysieren. Zur Vereinfachung der Demonstration wird das Batch-Einfügen als mehrere Einfügungen neu geschrieben.

Machen wir zunächst ein paar kleine Experimente. Die vereinfachte Tabellenstruktur sieht wie folgt aus

TABELLE ERSTELLEN `t1` (
 `id` int(11) NICHT NULL AUTO_INCREMENT,
 `ein` varchar(5),
 `b` varchar(5),
 Primärschlüssel (`id`),
 EINDEUTIGER SCHLÜSSEL `uk_name` (`a`,`b`)
);

Versuch 1:

Wenn zwei Batch-Einfügungen derselben Reihenfolge gleichzeitig ausgeführt werden und der Datensatz nicht vorhanden ist, wechselt der zweite in den Sperrwartezustand.

t1 t2
beginnen; beginnen;
Ignorieren in t1(a, b)values("1", "1") einfügen; Erfolg
Ignorieren in t1(a, b)values("1", "1") einfügen; Wartezustand für Sperre

Sie können den aktuellen Sperrstatus sehen

mysql> wähle * aus information_schema.innodb_locks;
+-------------+----------+-----------+---------------+-------------+------------+------------+------------+-----------+-----------+-----------+
| Sperr-ID | Sperr-TRX-ID | Sperrmodus | Sperrtyp | Sperrtabelle | Sperrindex | Sperrbereich | Sperrseite | Sperraufzeichnung | Sperrdaten |
+-------------+----------+-----------+---------------+-------------+------------+------------+------------+-----------+-----------+-----------+
| 31AE:54:4:2 | 31AE | S | AUFZEICHNUNG | `d1`.`t1` | `uk_name` | 54 | 4 | 2 | '1', '1' |
| 31AD:54:4:2 | 31AD | X | AUFZEICHNUNG | `d1`.`t1` | `uk_name` | 54 | 4 | 2 | '1', '1' |
+-------------+----------+-----------+---------------+-------------+------------+------------+------------+-----------+-----------+-----------+

Wenn wir den Einfügevorgang der Transaktion t1 ausführen, werden keine Sperrhaltepunkte angezeigt. Dies hängt mit dem Prinzip des MySQL-Einfügevorgangs zusammen.

Einfügen fügt eine implizite Sperre hinzu. Was ist eine implizite Sperre? Implizite Sperre bedeutet keine Sperre

Beim Einfügen von Datensätzen zum Zeitpunkt t1 werden keine Sperren angewendet. Zu diesem Zeitpunkt wurde die Transaktion t1 noch nicht festgeschrieben. Wenn die Transaktion t2 versucht, etwas einzufügen, findet sie diesen Datensatz. t2 versucht, die S-Sperre zu erhalten und ermittelt, ob die Transaktions-ID im Datensatz aktiv ist. Wenn sie aktiv ist, bedeutet dies, dass die Transaktion nicht beendet wurde. Dies hilft t1 dabei, seine implizite Sperre in eine explizite Sperre (X-Sperre) zu aktualisieren.

Der Quellcode lautet wie folgt

t2 Ergebnis des Erwerbs der S-Sperre: DB_LOCK_WAIT

Versuch 2:

Deadlock aufgrund inkonsistenter Batch-Einfügereihenfolge

t1 t2
beginnen
einfügen in t1(a, b)values("1", "1"); Erfolg
einfügen in t1(a, b)values("2", "2"); Erfolg
einfügen in t1(a, b)values("2", "2"); t1 versucht, eine S-Sperre zu erhalten, wertet die implizite Sperre von t2 zu einer expliziten X-Sperre auf und tritt in DB_LOCK_WAIT ein.
einfügen in t1(a, b)values("1", "1"); t2 versucht, eine S-Sperre zu erhalten, wodurch die implizite Sperre von t1 in eine explizite X-Sperre umgewandelt wird, was zu einem Deadlock führt.
------------------------
Zuletzt erkannter Deadlock
------------------------
181101 9:48:36
*** (1) TRANSAKTION:
TRANSAKTION 3309, AKTIV 215 Sek. Einfügen
MySQL-Tabellen in Verwendung 1, gesperrt 1
LOCK WAIT 3 Sperrstruktur(en), Heap-Größe 376, 2 Zeilensperre(n), Undo-Log-Einträge 2
MySQL-Thread-ID 2, OS-Thread-Handle 0x70000a845000, Abfrage-ID 58, Localhost-Root-Update
einfügen in t1(a, b)values("2", "2")
*** (1) WARTEN AUF DIE GEWÄHRUNG DIESER SPERRE:
Datensatzsperren, Bereichs-ID 55, Seitennummer 4, n Bits 72, Index „uk_name“ der Tabelle „d1“. „t1“ TRX-ID 3309, Sperrmodus S, wartend
Datensatzsperre, Heap Nr. 3 PHYSIKALISCHER DATENSATZ: n_Felder 3; kompaktes Format; Infobits 0
 0: Länge 1; Hex 32; aufsteigend 2;;
 1: Länge 1; Hex 32; aufsteigend 2;;
 2: Länge 4; Hex 80000002; aufsteigend ;;

*** (2) TRANSAKTION:
TRANSAKTION 330A, AKTIV 163 Sek. Einfügen
MySQL-Tabellen in Verwendung 1, gesperrt 1
3 Sperrstruktur(en), Heap-Größe 376, 2 Zeilensperre(n), Undo-Log-Einträge 2
MySQL-Thread-ID 3, OS-Thread-Handle 0x70000a888000, Abfrage-ID 59, Localhost-Root-Update
einfügen in t1(a, b)values("1", "1")
*** (2) HÄLT DAS SCHLOSS:
Datensatzsperren, Speicherplatz-ID 55, Seitennummer 4, n Bits 72, Index „uk_name“ der Tabelle „d1“. „t1“, TRX-ID 330A, Sperrmodus X sperrt Datensatz, aber nicht Lücke
Datensatzsperre, Heap Nr. 3 PHYSIKALISCHER DATENSATZ: n_Felder 3; kompaktes Format; Infobits 0
 0: Länge 1; Hex 32; aufsteigend 2;;
 1: Länge 1; Hex 32; aufsteigend 2;;
 2: Länge 4; Hex 80000002; aufsteigend ;;

*** (2) WARTEN AUF DIE GEWÄHRUNG DIESER SPERRE:
Datensatzsperren, Bereichs-ID 55, Seitennummer 4, n Bits 72, Index „uk_name“ der Tabelle „d1“. „t1“, TRX-ID 330A, Sperrmodus S, wartend
Datensatzsperre, Heap Nr. 2 PHYSIKALISCHER DATENSATZ: n_Felder 3; kompaktes Format; Infobits 0
 0: Länge 1; Hex 31; aufsteigend 1;;
 1: Länge 1; Hex 31; aufsteigend 1;;
 2: Länge 4; Hex 80000001; aufsteigend ;;

*** WIR MACHEN DIE TRANSAKTION ZURÜCK (2)

Wie kann man ein solches Problem lösen?

Eine mögliche Lösung besteht darin, die Daten nach der Sortierung auf der Anwendungsebene einzufügen.

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. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • Ausführliche Erläuterung der Mysql-Deadlock-Anzeige und Deadlock-Entfernung
  • Die normale Methode der MySQL-Deadlock-Prüfungsverarbeitung
  • Ursachen und Lösungen für MySQL-Deadlocks
  • Detaillierte Analyse von MySQL-Deadlock-Problemen
  • Analyse eines MySQL-Deadlock-Szenariobeispiels
  • Ein magischer MySQL-Deadlock-Troubleshooting-Datensatz
  • Analyse des Purge-Deadlock-Problems in der MySQL-Datenbank
  • Detaillierte Erläuterung der verteilten Deadlock-Erkennung und -Beseitigung durch SQL

<<:  Der vollständige Code der im Uniapp-Applet enthaltenen Radardiagrammkomponente

>>:  Detaillierte Erläuterung des Aufbaus und der Schnittstellenverwaltung des Docker Private Warehouse

Artikel empfehlen

Einführung in die MySQL-Optimierung für die Unternehmensproduktion

Im Vergleich zu anderen großen Datenbanken wie Or...

Lösung für den MySQL-Server-Anmeldefehler ERROR 1820 (HY000)

Fehlerseite: Melden Sie sich beim MySQL-Server an...

Ist es einfach, mit Vue3 eine Popup-Komponente zu kapseln?

Inhaltsverzeichnis Zusammenfassung zuerst: 🌲🌲 Vor...

Eine kurze Erläuterung der Situationen in MySQL, die zu Indexfehlern führen

Hier einige Tipps von Ausbildungsstätten und mein...

Mysql NULL verursachte die Grube

Verwenden von NULL in Vergleichsoperatoren mysql&...

Beispiel zum Verlassen der Schleife in Array.forEach in js

Inhaltsverzeichnis forEach() Methode So springen ...

Detailliertes Tutorial zur Offline-Installation von MySQL unter CentOS7

1. Löschen Sie die ursprüngliche MariaDB, sonst k...

So erstellen Sie PHP7 mit einem benutzerdefinierten Docker-Image

Führen Sie zunächst eine einfache Docker-Installa...

Einführung in Netzwerktreiber für Linux-Geräte

Kabelgebundenes Netzwerk: Ethernet Drahtloses Net...

Vue3-Kompilierungsprozess - Quellcodeanalyse

Vorwort: Vue3 ist schon seit langem verfügbar. Vo...

Stellen Sie die Grafana+Prometheus-Konfiguration mit Docker bereit

docker-compose-monitor.yml Version: '2' N...

Vue Uniapp realisiert den Segmentierungseffekt

In diesem Artikel wird der spezifische Code von V...

MySQL fügt schnell 100 Millionen Testdaten ein

Inhaltsverzeichnis 1. Erstellen Sie eine Tabelle ...