Wie können die Transaktionseigenschaften von MySQL InnoDB sichergestellt werden?

Wie können die Transaktionseigenschaften von MySQL InnoDB sichergestellt werden?

Vorwort

Wenn Sie jemand fragt: „Was sind die Merkmale von Datenbanktransaktionen?“ Sie können schnell auf die Fragen Atomizität, Konsistenz, Isolation und Dauerhaftigkeit antworten, die die ACID-Eigenschaften darstellen. Wissen Sie also, wie InnoDB diese Transaktionseigenschaften garantiert? Wenn Sie das wissen, können Sie diesen Artikel einfach überspringen (#^.^#)

Lassen Sie mich zunächst das Fazit darlegen:

  • Redo-Log wird verwendet, um die Persistenz von Transaktionen sicherzustellen
  • Undo-Log Rollback-Log stellt die Atomizität der Transaktionen sicher
  • Undo-Log + Redo-Log gewährleisten Transaktionskonsistenz
  • Sperren (gemeinsam genutzte Sperren, Sperren exklusiv) werden verwendet, um die Transaktionsisolierung sicherzustellen.

Redo-Protokoll

Das Redo-Log-Redo-Log ist in zwei Teile unterteilt: Der eine ist der Redo-Log-Puffer im Speicher, der leicht verloren gehen kann, der andere ist die Redo-Log-Datei, die dauerhaft ist. InnoDB erreicht Persistenz durch den Force Log at Commit-Mechanismus. Beim Commit müssen alle Transaktionsprotokolle zur Persistenz zunächst in die Redo-Log-Datei geschrieben werden, und die Transaktion gilt erst nach Abschluss des Commit-Vorgangs als abgeschlossen.

InnoDB schreibt den Inhalt des Redo-Log-Puffers in den folgenden Situationen in die Redo-Log-Datei:

  • Der Master-Thread leert den Redo-Log-Puffer jede Sekunde in die Redo-Log-Datei.
  • Wenn jede Transaktion festgeschrieben wird
  • Wenn der verbleibende Speicherplatz im Redo-Log-Pufferpool weniger als 1/2 beträgt

Um sicherzustellen, dass jedes Protokoll in die Redo-Logdatei geschrieben wird, muss die InnoDB-Speicher-Engine jedes Mal, wenn der Protokollpuffer in die Redo-Logdatei geschrieben wird, einen fsync-Vorgang (Flush) aufrufen. Dies ist jedoch nicht absolut. Benutzer können die Strategie zum Leeren von Redo-Protokollen auf die Festplatte steuern, indem sie den Parameter innodb_flush_log_at_trx_commoit ändern, der beim Festschreiben einer großen Anzahl von Transaktionen als Optimierungspunkt verwendet werden kann.

  • Der Standardwert 1 gibt an, dass beim Festschreiben einer Transaktion ein fsync-Vorgang aufgerufen werden muss.
  • 0 bedeutet, dass beim Festschreiben einer Transaktion der Redo-Log-Cache nicht sofort in die Redo-Log-Datei geschrieben wird, sondern dass in Intervallen des Master-Threads Fsync-Vorgänge ausgeführt werden.
  • 2 bedeutet, dass das Redo-Log beim Festschreiben der Transaktion in die Redo-Log-Datei geschrieben wird, es wird jedoch nur in den Dateisystem-Cache geschrieben und es wird kein fsync-Vorgang ausgeführt.
    Die Effizienz von fsync hängt von der Leistung der Festplatte ab. Daher bestimmt die Leistung der Festplatte die Leistung der Transaktionsübermittlung, d. h. die Leistung der Datenbank. Wenn Sie also jemand fragt, wie Sie die MySQL-Datenbank optimieren können, vergessen Sie die Hardware nicht. Bitten Sie ihn, die Festplattenkonfiguration zu verbessern und auf SSD-Solid-State-Laufwerke umzusteigen. Redo-Protokolle werden in 512-Byte-Blöcken gespeichert, die als Redo-Log-Blöcke bezeichnet werden. Sie haben die gleiche Größe wie Festplattensektoren, was bedeutet, dass das Schreiben von Redo-Protokollen Atomizität garantieren kann und keine Doublewrite-Technologie erfordert. Es verfügt über die folgenden drei Funktionen:
  • Redo-Logs werden auf der InnoDB-Ebene generiert
  • Das Redo-Log ist ein physisches Formatprotokoll, das die Änderungen auf jeder Seite aufzeichnet.
  • Redo-Protokolle werden während Transaktionen kontinuierlich und sequenziell geschrieben.

Rollback-Protokoll Undo-Protokoll

Um die Atomizität von Transaktionen sicherzustellen, sichern Sie die Daten vor der Verarbeitung zunächst an einem Ort (der Ort, an dem die Datensicherung gespeichert wird, wird als Undo-Protokoll bezeichnet) und ändern Sie dann die Daten. Wenn ein Fehler auftritt oder der Benutzer eine ROLLBACK-Anweisung ausführt, kann das System die Sicherung im Undo-Protokoll verwenden, um die Daten in den Zustand vor Beginn der Transaktion wiederherzustellen.

Das Undo-Protokoll implementiert die Multi-Version Concurrency Control (MVCC), um die Transaktionsisolierung sicherzustellen.

Das Rollback-Log unterscheidet sich vom Redo-Log. Es handelt sich um ein logisches Log, das alle Änderungen an der Datenbank logisch rückgängig macht. Wenn eine Transaktion zurückgesetzt wird, geschieht eigentlich das Gegenteil von dem, was sie vorher getan hat. Für jedes INSERT führt die InnoDB-Speicher-Engine ein DELETE aus; für jedes UPDATE führt die InnoDB-Speicher-Engine ein umgekehrtes UPDATE aus.

Das Undo-Protokoll kann nicht unmittelbar nach dem Festschreiben einer Transaktion gelöscht werden, da möglicherweise andere Transaktionen das Undo-Protokoll verwenden müssen, um die vorherige Version des Zeilendatensatzes abzurufen. Wenn eine Story-Aufgabe übermittelt wird, wird das Undo-Protokoll in eine verknüpfte Liste eingefügt. Ob das Undo-Protokoll gelöscht werden kann, hängt von den folgenden zwei Situationen ab:

  • Einfüge-Rückgängig-Protokoll: Der Datensatz des Einfügevorgangs ist nur für die Transaktion selbst und nicht für andere Transaktionen sichtbar (dies ist eine Anforderung der Transaktionsisolation). Daher kann das Rückgängig-Protokoll direkt nach dem Festschreiben der Transaktion gelöscht werden. Es ist kein Spülvorgang erforderlich.
  • Update-Rückgängig-Protokoll: zeichnet die durch Lösch- und Aktualisierungsvorgänge generierten Rückgängig-Protokolle auf. Das Undo-Protokoll muss möglicherweise einen MVCC-Mechanismus bereitstellen, sodass es nicht gelöscht werden kann, wenn die Transaktion festgeschrieben wird. Beim Senden wird es in die verknüpfte Liste des Rückgängig-Protokolls eingefügt und wartet darauf, dass der Bereinigungsthread die endgültige Löschung durchführt.

Sperren

Das Implementierungsprinzip der Transaktionsisolation ist die Sperre, daher kann die Isolation auch als Parallelitätskontrolle, Sperre usw. bezeichnet werden. Die Transaktionsisolierung erfordert, dass die Objekte jeder Lese-/Schreibtransaktion von den Operationsobjekten anderer Transaktionen getrennt werden. Darüber hinaus müssen beispielsweise beim Bedienen der LRU-Liste im Pufferpool sowie beim Löschen, Hinzufügen und Verschieben von Elementen in der LRU-Liste Sperren eingesetzt werden, um die Konsistenz sicherzustellen.

Arten von Schlössern

InnoDB verfügt über zwei Haupttypen von Sperren: Zeilensperren und Intention-Sperren

Sperren auf Zeilenebene:

  • Eine gemeinsame Sperre (Lesesperre S) ermöglicht einer Transaktion das Lesen einer Datenzeile. Eine Transaktion kann eine Datensatzzeile erst lesen, nachdem sie eine gemeinsam genutzte S-Sperre für die Zeile erhalten hat und verhindert, dass andere Transaktionen X-Sperren darauf anwenden. Der Zweck gemeinsam genutzter Sperren besteht darin, die gleichzeitige Lese- und Lesezugriffe zu verbessern.
  • Eine exklusive Sperre (Schreibsperre X) ermöglicht einer Transaktion, eine Datenzeile zu löschen oder zu aktualisieren. Eine Transaktion kann eine Zeile erst ändern oder löschen, nachdem sie eine exklusive X-Sperre für die Zeile erhalten hat. Der Zweck der exklusiven Sperre besteht darin, die Datenkonsistenz sicherzustellen.

Mit Ausnahme von S und S sind alle anderen Sperren auf Zeilenebene inkompatibel.

Absichtssperre:

  • Absicht gemeinsame Sperre (Lesesperre IS): Wenn eine Transaktion eine gemeinsame Sperre für mehrere Datenzeilen in einer Tabelle erhalten möchte, muss die Transaktion zuerst die IS-Sperre der Tabelle erhalten, bevor sie einer Datenzeile eine gemeinsame Sperre hinzufügt.
  • Absicht exklusive Sperre (Schreibsperre IX). Wenn eine Transaktion exklusive Sperren für mehrere Datenzeilen in einer Tabelle erhalten möchte, muss die Transaktion zuerst die IX-Sperre der Tabelle erhalten, bevor sie einer Datenzeile eine exklusive Sperre hinzufügt.

Erklären Sie die Absichtssperre

Der Hauptzweck von IX- und IS-Sperren besteht darin, anzuzeigen, dass jemand eine Zeile sperrt oder eine Zeile in der Tabelle sperren wird.

Der Hauptzweck von Absichtssperren besteht darin, auszudrücken, dass eine Transaktion eine Datenzeile sperrt oder sperren wird. Wenn beispielsweise Transaktion A eine X-Sperre auf eine Zeile des Datensatzes r anwenden möchte, wendet InnoDB zuerst eine IX-Sperre auf die Tabelle an und sperrt dann die X-Sperre auf Datensatz r. Bevor Transaktion A abgeschlossen ist, möchte Transaktion B eine vollständige Tabellenoperation ausführen. Zu diesem Zeitpunkt weist IX auf Tabellenebene Transaktion B direkt an, zu warten, ohne feststellen zu müssen, ob jede Zeile in der Tabelle gesperrt ist. Der Wert absichtlich exklusiver Sperren liegt in der Einsparung von InnoDBs Sperrpositionierung und Verarbeitungsleistung. Beachten Sie auch, dass Absichtssperren nur bei vollständigen Tabellenscans blockieren.

Sperralgorithmus

InnoDB verfügt über drei Zeilensperralgorithmen:

  • Datensatzsperre: Sperre für einen einzelnen Zeilendatensatz
  • Lückensperre: Lückensperre, sperrt einen Bereich, nicht den Datensatz selbst
  • Next-Key Lock: Kombiniert Gap Lock und Record Lock, um einen Bereich und den Datensatz selbst zu sperren. Das Hauptproblem, das gelöst werden muss, ist das Phantomlesen unter der Isolationsebene REPEATABLE READ. Weitere Informationen zu Transaktionsisolationsebenen finden Sie im Artikel.

Hier sprechen wir hauptsächlich über Next-Key Lock. Next-Key Lock sperrt nicht einen einzelnen Wert, sondern einen Bereich. Sein Zweck besteht darin, zu verhindern, dass mehrere Transaktionen Datensätze in denselben Bereich einfügen und dadurch Phantom-Lesevorgänge verursachen.

Beachten Sie, dass bei Verwendung eines eindeutigen Index die Next-Key-Sperre auf eine Datensatzsperre herabgestuft wird. Dies bedeutet, dass nur der Index selbst und nicht der Bereich gesperrt wird. Das heißt, die Voraussetzung für Next-Key Lock ist, dass die Transaktionsisolationsstufe RR ist und der abgefragte Index ein nicht eindeutiger Index oder ein Primärschlüsselindex ist.

Lassen Sie uns dies anhand eines Beispiels im Detail erklären.

Erstellen Sie zunächst eine Tabelle:

TABELLE ERSTELLEN (id int, f_id int, PRIMARY KEY (id), KEY(f_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8
in T einfügen SELECT 1,1;
in T einfügen SELECT 3,1;
in T einfügen SELECT 5,3;
in T einfügen SELECT 7,6;
einfügen in T SELECT 10,8;

Transaktion A führt die folgende Anweisung aus:

Wählen Sie * aus T, wobei f_id = 3 für Update ist

Zu diesem Zeitpunkt verwendet die SQL-Anweisung einen nicht eindeutigen Index. Daher wird Next-Key Locking verwendet und es gibt zwei Indizes, die separat gesperrt werden müssen.

Für den gruppierten Index fügt es nur dem Index mit der ID 5 eine Datensatzsperre hinzu. Für den Hilfsindex wird Next-Key Lock hinzugefügt, um den Bereich (1,3) zu sperren. Besonders wichtig ist zu beachten, dass die InnoDB-Speicher-Engine auch dem nächsten Schlüsselwert des Hilfsindexes ein Gap Lock hinzufügt, also eine Sperre im Bereich (3,6).

Wenn Sie daher die folgenden Anweisungen in einer neuen Sitzung ausführen, wird ein Fehler [Err] 1205 - Lock wait timeout exceeded; try restarting transaction gemeldet:

select * from T where id = 5 lock in share MODE – kann nicht ausgeführt werden, da Transaktion A eine X-Sperre zum Wert von id = 5 hinzugefügt hat und die Ausführung blockiert wird. INSERT INTO T SELECT 4,2 – kann nicht ausgeführt werden, der Wert des Hilfsindex ist 2, was im Bereich von (1,3) liegt und die Ausführung wird blockiert. INSERT INTO T SELECT 6,5 – kann nicht ausgeführt werden, die Lückensperre sperrt den Bereich von (3,6) und die Ausführung wird blockiert.

Stellen Sie sich nun vor, dass Transaktion A den Datensatz mit f_id = 5 sperrt. Normalerweise gibt es eine Lückensperre, die (5, 6) sperrt. Wenn es keine Lückensperre für (5, 6) gibt, kann der Benutzer einen Datensatz mit dem Index f_id 5 einfügen. Dann gibt Transaktion A bei einer erneuten Abfrage einen anderen Datensatz zurück, was zu Phantom-Lesevorgängen führt.

Wenn unsere Transaktion A beispielsweise select * from T where f_id = 10 FOR UPDATE ausführt, können in der Tabelle keine Daten gefunden werden. Aufgrund von Next-Key Lock wird jedoch (8, +∞) gesperrt. Wir können INSERT INTO T SELECT 6,11 nicht erfolgreich einfügen, was das Phantom-Read-Problem grundsätzlich löst.

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:
  • Analyse der Unterschiede zwischen Mysql InnoDB und MyISAM
  • So ermitteln Sie die Höhe des MySQL InnoDB B+-Baums
  • Unterschiede zwischen MySQL MyISAM und InnoDB
  • Beschreiben Sie kurz die MySQL InnoDB-Speicher-Engine
  • Detaillierte Erläuterung der MySQL Innodb-Speicherstruktur und der Speicherung von Nullwerten
  • Schritte zur Überprüfung der MySQL InnoDB-Row_ID-Grenzwertüberschreitung
  • MySQL-Startfehler InnoDB: Sperren nicht möglich/ibdata1-Fehler
  • Ausführliche Erklärung des Sperrmechanismus in MySQL InnoDB
  • Detaillierte Erklärung, wie MySQL (InnoDB) mit Deadlocks umgeht
  • MySQL-Lernen (VII): Detaillierte Erläuterung des Implementierungsprinzips des Innodb Storage Engine-Index
  • MySQL slow_log-Tabelle kann nicht in InnoDB-Engine geändert werden – detaillierte Erklärung
  • Zusammenfassung wichtiger Komponenten von MySQL InnoDB

<<:  Ausführliche Erklärung der Iteratoren in ECMAScript

>>:  Detaillierte Erläuterung der Konfiguration des Samba-Ordnerfreigabeservers unter CentOS

Artikel empfehlen

So finden Sie identische Dateien in Linux

Während der Nutzung des Computers entsteht im Sys...

Lokale MySQL-Installation und Problemlösung

Vorwort Dieser Artikel ist ziemlich ausführlich u...

Zugriffsvorgang im MySQL-Befehlszeilenmodus MySQL-Datenbankvorgang

Nutzungsumgebung Geben Sie im cmd-Modus mysql --v...

Detaillierte Erläuterung des Mysql Self-Join-Abfragebeispiels

Dieser Artikel beschreibt die Mysql-Self-Join-Abf...

Eine kurze Analyse der Verwendung von watchEffect in Vue3

Vorwort Jeder sollte mit der Watch-API in vue2 ve...

Warum wird mir die Zugriffsschnittstelle für Docker Tomcat nicht angezeigt?

Frage: Kann der Ursprungsserver keine Darstellung...

Mehrere Methoden zum Ausführen von SQL-Dateien unter der MySQL-Befehlszeile

Inhaltsverzeichnis Die erste Methode: Wenn die My...

Detaillierte Erklärung der Funktionen jedes Ports von Tomcat

Aus der Tomcat-Konfigurationsdatei können wir ers...