Ein Artikel zum detaillierten Verständnis von MySQL-Zeilensperren, Tabellensperren und Lückensperren

Bereit zu arbeiten

Erstellen Sie die Tabelle tb_innodb_lock

Tabelle löschen, falls vorhanden test_innodb_lock; 
CREATE TABLE test_innodb_lock ( 
    a INT (11), 
    b VARCHAR (20) 
) ENGINE INNODB DEFAULT charset = utf8; 
in test_innodb_lock Werte einfügen (1, 'a'); 
in test_innodb_lock Werte einfügen (2, 'b'); 
in test_innodb_lock Werte einfügen (3, 'c'); 
in test_innodb_lock Werte einfügen (4, 'd'); 
in test_innodb_lock Werte einfügen (5, 'e');

Index erstellen

Erstelle den Index idx_lock_a für test_innodb_lock (a); 
Erstelle den Index idx_lock_b für test_innodb_lock (b).

MySQL Lock Demo

  • Ändern Sie zuerst die automatische Festschreibungstransaktion in manuelles Festschreiben:set autocommit=0;

  • Wir starten zwei Sitzungsfenster A und B und simulieren, dass eines das Schloss greift und das andere blockiert wird, ohne zu greifen.

Zeilensperre (Schreiben & Lesen)

  • Eine Fensterausführung

update test_innodb_lock set b = 'a1' wobei a = 1;
SELECT * from test_innodb_lock;

1.png

Wir können das aktualisierte Ergebnis in Fenster A sehen

  • B Fensterausführung

SELECT * from test_innodb_lock;

2.png

Wir können sehen, dass das B-Fenster das aktualisierte Ergebnis nicht sehen kann, aber die alten Daten immer noch gesehen werden. Dies liegt daran, dass der Datensatz von a = 1 durch die vom A-Fenster ausgeführte SQL-Anweisung gesperrt wurde und die Festschreibungsoperation nicht ausgeführt wurde. Fenster B sieht also immer noch die alten Daten. Dies ist das "Lese-Commit" in der MySQL-Isolationsstufe.

  • Fenster A führt eine Festschreibungsoperation aus

VERPFLICHTEN;


  • Abfrage von Fenster B.

SELECT * from test_innodb_lock;

3.png

Zu diesem Zeitpunkt haben wir festgestellt, dass Fenster B die neuesten Daten gelesen hat

Zeilensperre (Schreiben & Schreiben)

  • Fenster A führt die Aktualisierung eines Datensatzes = 1 durch

update test_innodb_lock set b = 'a2' wobei a = 1;

Zu diesem Zeitpunkt gibt es kein Commit und die Sperre wird von Fenster A gehalten.

  • Fenster B aktualisiert auch den Datensatz von a = 1

update test_innodb_lock set b = 'a3' wobei a = 1;

4.png

Wie Sie sehen können, wurde Fenster B blockiert, da Fenster A noch kein Commit ausgeführt hat und die Sperre weiterhin hält. Fenster B kann die in Zeile a = 1 aufgezeichnete Sperre nicht greifen, daher wurde das Warten blockiert.

  • Fenster A führt eine Festschreibungsoperation aus

VERPFLICHTEN;

  • Änderungen im Fenster B.

5.png

Sie können sehen, dass Fenster B zu diesem Zeitpunkt erfolgreich ausgeführt wurde

Tischschloss

Wenn ein Index fehlschlägt, wird die Zeilensperre zu einer Tabellensperre aktualisiert. Eine der Methoden für einen Indexfehler besteht darin, den Index automatisch oder manuell zu ändern. Das a-Feld selbst ist eine Ganzzahl, wir fügen Anführungszeichen hinzu, es wird zu einem String, diesmal ist der Index ungültig.

  • Fenster A aktualisiert den Datensatz von a = 1

Update test_innodb_lock set b = 'a4' wobei a = 1 oder a = 2;

  • Fenster B aktualisiert den Datensatz von a = 2

update test_innodb_lock set b = 'b1' wobei a = 3;

6.png

Zu diesem Zeitpunkt wurde festgestellt, dass, obwohl die aktualisierten Zeilen von Fenster A und B unterschiedlich waren, Fenster B immer noch blockiert war, da der Index von Fenster A fehlschlug, was dazu führte, dass die Zeilensperre auf Tabellensperre aktualisiert wurde, wodurch die gesamte Tabelle und das Indexfenster gesperrt wurden B ist gesperrt.

  • Fenster A führt eine Festschreibungsoperation aus

VERPFLICHTEN;

  • Änderungen im Fenster B.

7.png

Sie können sehen, dass Fenster B zu diesem Zeitpunkt erfolgreich ausgeführt wurde

Gap Lock

  • Was ist ein Lückenschloss?

Wenn wir Bereichsbedingungen zum Abfragen von Daten verwenden, sperrt InnoDB die Daten in diesem Bereich. Zum Beispiel gibt es 4 Daten mit der ID: 1, 3, 5 und 7, wir suchen nach Daten im Bereich von 1-7. Dann wird 1-7 gesperrt. 2, 4 und 6 liegen ebenfalls im Bereich von 1 bis 7, aber diese Datensätze existieren nicht. Diese 2, 4 und 6 werden als Lücken bezeichnet.

  • Der Schaden von Gap Lock

Bei der Suche im Bereich werden alle Daten im gesamten Bereich gesperrt. Auch einige Daten, die in diesem Bereich nicht vorhanden sind, werden unschuldig gesperrt. Ich möchte beispielsweise 2 in 1, 3, 5 und 7 einfügen, diesmal 1 -7 ist gesperrt und 2 kann überhaupt nicht eingefügt werden. In einigen Szenarien hat dies einen großen Einfluss auf die Leistung

  • Gap Lock Demo

Wir ändern zuerst den Wert von Feld a auf 1, 3, 5, 7, 9

  • Fenster A aktualisiert die Daten im Bereich a = 1 ~ 7

update test_innodb_lock set b = 'b5' wobei a> 1 und a <7;

  • Fenster B fügt Daten bei a = 2 ein

in test_innodb_lock Werte einfügen (2, "b6");

8.png

Zu diesem Zeitpunkt wurde festgestellt, dass die Operation zum Aktualisieren von a = 2 in Fenster B gewartet hat, da die Daten im Bereich von 1 bis 7 durch die Lücke gesperrt und gesperrt sind. Nur wenn Fenster A ein Commit ausführt und Fenster B a = 2 ist, kann die Aktualisierung erfolgreich sein

Zeilensperranalyse

  • Führen Sie SQL-Analysebefehle aus

Status anzeigen wie 'innodb_row_lock%';

9.png

  • Beschreibung des Variablennamens

    • Innodb_row_lock_current_waits: Die Anzahl der Sperren, auf die derzeit gewartet wird.

    • Innodb_row_lock_time: Die Zeitspanne vom Systemstart bis zur aktuellen Sperre.

    • Innodb_row_lock_time_avg: Die durchschnittliche Wartezeit auf die Sperre.

    • Innodb_row_lock_time_max: Die längste Wartezeit der Sperre seit dem Start des Systems.

    • Innodb_row_lock_waits: Die Gesamtzahl der Wartezeiten auf Sperren nach dem bisherigen Systemstart.

Zu guter Letzt

Ich danke Ihnen allen, dass Sie hier gesehen haben. Der Artikel weist Mängel auf. Wenn Sie der Meinung sind, dass er gut geschrieben ist, geben Sie mir einen Daumen hoch


Ich denke du magst

Origin blog.51cto.com/14849432/2542676
Empfohlen
Rangfolge