Vorwort Kürzlich wurde ich in einem Interview gefragt, wie die InnoDB-Engine von MySQL Transaktionen implementiert oder wie sie die ACID-Funktionen implementiert. Ich konnte damals keine gute Antwort geben, also habe ich es selbst zusammengefasst und aufgeschrieben. Die vier Merkmale von ACID-Transaktionen Die vier Hauptmerkmale von Transaktionen sind ACID, A-Atomizität, C-Konsistenz, I-Isolation und D-Haltbarkeit. Konsistenz ist das ultimative Ziel und Atomarität, Isolation und Persistenz sind Maßnahmen, die ergriffen werden, um Konsistenz sicherzustellen. Die Reihenfolge, die ich geschrieben habe, basiert also nicht auf ACID. Ich habe Konsistenz ans Ende gesetzt und die Reihenfolge wird zu ADIC. Atomarität (A) Atomarität bedeutet, dass eine Transaktion eine unteilbare Arbeitseinheit ist. Entweder wird sie vollständig erfolgreich ausgeführt oder sie schlägt fehl, ohne dass ein Zwischenzustand auftritt oder nur ein Teil davon ausgeführt wird. Die InnoDB-Engine von MySQL wird durch ein Undo-Log (Rollback-Log) implementiert, das sicherstellen kann, dass alle erfolgreich ausgeführten SQL-Anweisungen rückgängig gemacht werden, wenn ein Rollback einer Transaktion durchgeführt wird. Das Undo-Protokoll ist ein logisches Protokoll, das Informationen zur SQL-Ausführung aufzeichnet. Wenn eine Transaktion die Datenbank ändert, generiert InnoDB ein entsprechendes Undo-Protokoll. Wenn die Ausführung der Transaktion fehlschlägt oder ein Rollback aufgerufen wird, wodurch die Transaktion zurückgesetzt wird, setzt die InnoDB-Engine die Daten basierend auf den Datensätzen im Undo-Protokoll auf ihren vorherigen Zustand zurück. Beharrlichkeit (D) Persistenz bedeutet, dass, sobald eine Transaktion festgeschrieben ist, der Vorgang in der Datenbank dauerhaft ist und nachfolgende andere Vorgänge und ungewöhnliche Fehler keine Auswirkungen darauf haben sollten. Daher stellt InnoDB einen Pufferpool für MySQL bereit, der die Zuordnung einiger Datenseiten auf der Festplatte enthält. Obwohl der Pufferpool die Effizienz des Lesens und Schreibens von MySQL verbessert, bringt er auch neue Probleme mit sich. Das heißt, wenn MySQL plötzlich abstürzt, während die Daten gerade im Pufferpool aktualisiert und noch nicht auf der Festplatte aktualisiert wurden, führt dies zu Datenverlust und die Dauerhaftigkeit der Transaktion kann nicht garantiert werden. Da das Redo-Protokoll beim Festschreiben der Transaktion mit der Festplatte synchronisiert wird, kann bei einem MySQL-Absturz das Redo-Protokoll von der Festplatte gelesen werden, um die Daten wiederherzustellen. Dadurch wird die Persistenz der Transaktion sichergestellt. Das Redo-Protokoll verwendet eine Vorschreibmethode zum Aufzeichnen von Protokollen, d. h., das Protokoll wird zuerst aufgezeichnet und dann der Pufferpool aktualisiert. Dadurch wird sichergestellt, dass die Daten, solange sie im Redo-Protokoll gespeichert sind, auf der Festplatte gespeichert bleiben. Dies bedarf einiger Erklärungen. Das Redo-Protokoll wird ebenfalls auf die Festplatte geschrieben, und auch das Leeren wird auf die Festplatte geschrieben. Warum müssen wir zuerst das Redo-Protokoll aufzeichnen, anstatt es direkt zu leeren? Der Hauptgrund besteht darin, dass das Redo-Protokoll viel schneller ist als das Leeren. Der erste Punkt ist, dass das Redo-Protokoll ein Anfügevorgangsprotokoll ist, also ein sequentieller IO-Vorgang, während Dirty Flushing ein zufälliger IO-Vorgang ist, da die jedes Mal aktualisierten Daten nicht unbedingt benachbart, also zufällig sind. Der zweite Punkt ist, dass das Dirty Flushing in Einheiten von Datenseiten erfolgt (d. h. jedes Mal wird mindestens eine Datenseite von der Festplatte in den Speicher gelesen oder mindestens eine Datenseite auf die Festplatte geschrieben). Die Standardseitengröße von MySQL beträgt 16 KB. Bei jeder Änderung einer Seite muss die gesamte Seite auf die Festplatte geschrieben werden. Das Redo-Protokoll enthält nur die Vorgangsprotokolle, die tatsächlich auf die Festplatte geschrieben werden müssen. MySQL verfügt auch über ein Protokoll namens Binlog, das Vorgänge aufzeichnet. Was ist also der Unterschied zwischen Redo-Log und Binlog?
Das Redo-Protokoll wird zum Aufzeichnen des Aktualisierungscache verwendet, um sicherzustellen, dass die Persistenz der Transaktionen auch bei einem MySQL-Absturz nicht beeinträchtigt wird. Das Binärprotokoll wird zum Aufzeichnen verwendet, welche Vorgänge wann ausgeführt wurden, hauptsächlich mit Zeitpunkten, um sicherzustellen, dass die Daten zu einem bestimmten Zeitpunkt wiederhergestellt werden können. Es wird auch für die Master-Slave-Synchronisierung von Daten verwendet.
Das Redo-Log wird von der Speicher-Engine InnoDB implementiert (MyISAM hat kein Redo-Log), während das Binlog auch in jeder anderen Speicher-Engine auf MySQL-Serverebene verfügbar ist.
Standardmäßig wird das Redo-Protokoll auf die Festplatte geschrieben, wenn die Transaktion festgeschrieben wird. Die Richtlinie kann über den Parameter innodb_flush_log_at_trx_commit geändert werden, sodass das Redo-Protokoll nicht warten muss, bis die Transaktion festgeschrieben ist, bevor es auf die Festplatte geschrieben wird. Isolierung (I) Atomarität und Dauerhaftigkeit sind beides Maße, die auf einer einzelnen Transaktion basieren, während Isolation die Eigenschaft bezeichnet, dass mehrere Transaktionen voneinander isoliert sind und sich nicht gegenseitig beeinflussen.
Verriegelungsmechanismus Die Sperren in MySQL sind hauptsächlich Je nach Funktion: Lesesperre und Schreibsperre, je nach Aktionsbereich: Sperre auf Tabellenebene und Sperre auf Zeilenebene, Lesesperre: auch als „gemeinsame Sperre“ bekannt, bedeutet, dass mehrere Transaktionen eine Sperre gemeinsam nutzen können und nur auf Daten zugreifen, diese aber nicht ändern können. Schreibsperre: auch als „exklusive Sperre“ bekannt, kann Daten nicht mit anderen Transaktionen teilen. Wenn eine Transaktion eine exklusive Sperre für ein Datenelement erhält, können andere Transaktionen keine anderen Sperren für die Zeile erhalten, einschließlich gemeinsam genutzter Sperren und exklusiver Sperren. Sperre auf Tabellenebene: bedeutet, dass die gesamte Tabelle gesperrt wird, was zu schlechter Leistung führt. Verschiedene Speicher-Engines unterstützen unterschiedliche Sperrgranularitäten. Die MyISAM-Engine unterstützt Sperren auf Tabellenebene und die InnoDB-Engine unterstützt sowohl Sperren auf Tabellenebene als auch auf Zeilenebene. Sperre auf Zeilenebene: Die entsprechenden Zeilen, die bedient werden müssen, werden mit guter Leistung gesperrt. Absichtssperre: Eine Absichtssperre ist eine Sperre auf Tabellenebene. Wenn eine Transaktion bereits eine exklusive Sperre oder eine gemeinsame Sperre für bestimmte Daten in einer Tabelle hinzugefügt hat, kann eine Absichtssperre hinzugefügt werden. Auf diese Weise wird die Tabelle zuerst blockiert, wenn die nächste Transaktion die Tabelle sperren will und feststellt, dass die Absichtssperre bereits vorhanden ist. Wenn die Absichtssperre nicht hinzugefügt wurde, muss die zweite Transaktion, wenn sie die Tabelle sperren will, jeweils eine Zeile durchlaufen, um zu prüfen, ob gesperrte Daten vorhanden sind. Lückensperre: Die Lückensperre ist eine Sperre, die hinzugefügt wird, um Phantom-Lesevorgänge zu verhindern. Sie wird zu nicht vorhandenem freien Speicherplatz hinzugefügt, der zwischen zwei Indexdatensätzen oder dem Speicherplatz vor dem ersten Indexdatensatz oder nach dem letzten Indexdatensatz liegen kann (schließt jedoch nicht den aktuellen Datensatz ein). Dadurch wird sichergestellt, dass beim Ausführen der Lückensperre die neu hinzugefügten Daten blockiert werden, und es wird sichergestellt, dass die Anzahl der durch zwei Abfragen in einer Transaktion abgerufenen Datensätze konsistent ist. Next-Key-Lock: Next-Key-Lock ist eine Kombination aus Zeilensperre und Lückensperre, da die Lückensperre den aktuellen Datensatz nicht sperrt, während Next-Key-Lock auch den aktuellen Datensatz sperrt. Wenn eine Tabelle beispielsweise drei Datensätze enthält:
Wenn Sie dann SQL ausführen: select * from table where number = 17 for update, wird die Lückensperre gesperrt. Der Zahlenbereich ist (16, 17), (17, 20), aber die Next-Key-Sperre sperrt: Der Sperrmechanismus gewährleistet die Isolierung von Schreibvorgängen zwischen mehreren Transaktionen, während die Garantie von Lese- und Schreibvorgängen zwischen mehreren Transaktionen durch den MVCC-Mechanismus gewährleistet werden muss. MVCC-Mechanismus
MVCC wird hauptsächlich implementiert, indem jeder Datensatzzeile versteckte Spalten hinzugefügt und Undo-Protokolle verwendet werden. Die versteckten Spalten enthalten hauptsächlich die von der Datenzeile erstellte Versionsnummer (inkrementell), den Löschzeitpunkt, einen Zeiger auf das Undo-Protokoll usw. Wie stellt MVCC also die Lese-/Schreibisolation sicher? Es werden hauptsächlich zwei Vorgänge verwendet: Snapshot-Lesen und aktuelles Lesen.
Um die Effizienz der Parallelität zu gewährleisten, sperrt MVCC beim Lesen von Daten nicht. Beim Ausführen von select (normales select ohne Sperre) wird zuerst die Versionsnummer der aktuellen Daten gelesen. Wenn eine Transaktion diese Datenzeile ändert, bevor select ein Ergebnis zurückgibt, ist die Versionsnummer größer als zum Zeitpunkt der Ausführung von select. Um die Konsistenz der von select gelesenen Daten sicherzustellen, werden daher nur Daten gelesen, die kleiner oder gleich der aktuellen Version sind. Diese historische Version der Daten wird aus dem Undo-Protokoll abgerufen.
Beim Ausführen von Einfügen, Aktualisieren oder Löschen werden die Daten der neuesten Version gelesen und der aktuelle Datensatz gesperrt, um sicherzustellen, dass die Versionsnummer während des Vorgangs nicht durch andere Transaktionen geändert wird. Beispielsweise handelt es sich bei der normalen Auswahl um einen Snapshot-Lesevorgang. Dies bedeutet, dass es sich bei dem Lesevorgang möglicherweise um die historische Version der Daten handelt. Einfügen, Aktualisieren, Löschen, Auswählen ... Sperren im Freigabemodus, und Auswählen ... zum Aktualisieren lesen die aktuellen Daten, das heißt, sie lesen die neueste Version der Daten. Tatsächlich kann durch Festlegen der Isolationsstufe auf Serializable auch eine Lese-/Schreibisolation erreicht werden, die Parallelitätseffizienz ist jedoch viel geringer und wird daher im Allgemeinen selten verwendet. MVCC sperrt jedoch nicht beim Lesen, sondern nur beim Schreiben, wodurch die Parallelitätseffizienz verbessert wird. Der MVCC-Mechanismus gewährleistet die Lese-/Schreibisolation zwischen mehreren Transaktionen und erreicht dadurch eine Transaktionsisolation. Konsistenz (C) Konsistenz bezieht sich auf die Konsistenz der Daten vor und nach der Ausführung der Transaktion. Die Datenintegrität vor und nach der Transaktion wird nicht zerstört und der Datenstatus ist legal.
Die Integrität des Index (eindeutiger Index, keine Duplikate usw.), die Vervollständigung der Datenspalten (Feldtyp, Länge, Größe erfüllen die Anforderungen), Fremdschlüsseleinschränkungen usw.
Garantieren Sie Atomizität, Persistenz und Isolation. Wenn diese Eigenschaften nicht garantiert werden können, kann auch die Konsistenz nicht garantiert werden. Auf Datenbankebene gibt es zusätzlich zu den Garantien der oben genannten Funktionen Maßnahmen, um die Konsistenz der Felder sicherzustellen. Beispielsweise können keine Ganzzahlen übergeben werden und die Länge von Zeichenfolgen, Zeitformaten usw. darf die Spaltenbegrenzung nicht überschreiten. Allerdings müssen die Entwickler dies selbst auf Anwendungsebene sicherstellen. Darüber hinaus stellt MySQL durch ein zweiphasiges Transaktions-Commit auch die Datenkonsistenz zwischen Redo-Log und Binärlog sicher. Bei der Einführung in die Persistenz haben wir oben den Unterschied zwischen Redo-Log und Binlog erläutert. Der dritte Unterschied besteht darin, dass beim Festschreiben einer Transaktion standardmäßig sowohl das Redo-Log als auch das Binlog geschrieben werden. Wie koordinieren sie also die Konsistenz? Welches Protokoll wird geschrieben, um festzustellen, ob eine Transaktion erfolgreich abgeschlossen wurde?
Senden Sie das Redo-Protokoll an die Festplatte und ändern Sie den Status in den Vorbereitungsstatus. Führen Sie keine Operationen am Binärprotokoll aus.
1. Generieren Sie ein Binärprotokoll der Transaktionsvorgänge und schreiben Sie das Binärprotokoll auf die Festplatte. 2. Rufen Sie die Transaktions-Commit-Schnittstelle der Engine auf, um den Redo-Log-Status von „Vorbereiten“ auf „Commit“ zu ändern. Anschließend wird die Transaktion festgeschrieben. Zusammenfassen ACID und Konsistenz von MySQL-Transaktionen sind die ultimativen Ziele.
Oben finden Sie Einzelheiten dazu, wie MySQL ACID von Transaktionen implementiert. Weitere Informationen dazu, wie MySQL ACID von Transaktionen implementiert, finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Eine kurze Diskussion über die perfekte Anpassungslösung für das mobile Vue-Terminal
>>: Implementierungsprinzip und Codebeispiele für die Komprimierungsdatei des Linux-Befehls gzip
Beim Verwenden von Animation.css habe ich festges...
Problembeschreibung: Beim Einfügen chinesischer Z...
Wie können Sie in MySQL die Berechtigungen anzeig...
Mixin-Methode: Der Browser kann nicht kompilieren...
Ein zusammengesetzter Index (auch gemeinsamer Ind...
Inhaltsverzeichnis 1. Komponentenregistrierung 2....
Dieser Artikel stellt hauptsächlich die dynamisch...
Vorwort: Mit der kontinuierlichen Entwicklung der...
Inhaltsverzeichnis Überblick console.log konsole....
In diesem Artikel finden Sie das Installations-Tu...
Vor dem Verstecken: Nach dem Verstecken: CSS: Code...
Inhaltsverzeichnis 1. Nachfrage Methode 1 Methode...
Um mit Standard-CSS3 den Schatteneffekt eines Ele...
Das Folgende ist die Konfigurationsmethode unter ...
Inhaltsverzeichnis 1. Herunterladen 2. Bereitstel...