Dieser Artikel bietet Ihnen eine detaillierte Einführung (Codebeispiel) über die InnoDB-Speicher-Engine. Ich hoffe, dass er für Freunde hilfreich ist.
InnoDB gehört zur Storage-Engine-Schicht in MySQL und ist in Form eines Plug-Ins in die Datenbank integriert. Ab MySQL 5.5.8 wird InnoDB seine Standardspeicher-Engine. Die InnoDB-Speicher-Engine unterstützt Transaktionen und ihr Entwurfsziel ist hauptsächlich für OLTP-Anwendungen. Zu ihren Hauptfunktionen gehören: Unterstützung von Transaktionen, Zeilensperrdesign zur Unterstützung hoher Parallelität, Unterstützung von Fremdschlüsseln, automatische Wiederherstellung nach Abstürzen, Struktur der Cluster-Index-Organisationstabelle usw. (Verwandte Empfehlungen: MySQL-Tutorial)
Systemarchitektur
Die InnoDB-Speicher-Engine besteht aus drei Teilen: Speicherpool, Hintergrundthread und Festplattenspeicher.
Threads
InnoDB verwendet ein Multithreading-Modell, bei dem mehrere verschiedene Threads im Hintergrund für die Verarbeitung verschiedener Aufgaben zuständig sind
Master-Thread ist der Kern-Hintergrund-Thread, der hauptsächlich für die asynchrone Aktualisierung der Daten im Pufferpool auf der Festplatte verantwortlich ist, um die Datenkonsistenz sicherzustellen. Einschließlich schmutziger Seitenaktualisierung, zusammengeführtem Einfügungspuffer, UNDO-Seitenrecycling usw.
In der InnoDB-Speicher-Engine wird asynchrones IO (Async IO) häufig zur Verarbeitung von Schreib-IO-Anfragen verwendet. Die Aufgabe des IO-Threads ist hauptsächlich für den Rückruf dieser IO-Anfragen verantwortlich .
Nachdem die Transaktion festgeschrieben wurde, wird das von ihr verwendete Rückgängig-Protokoll möglicherweise nicht mehr benötigt. Daher ist Purge Thread erforderlich, um die zugewiesenen und verwendeten UNDO-Seiten wiederzuverwenden. InnoDB unterstützt mehrere Purge-Threads, die das Recycling von UNDO-Seiten beschleunigen, die CPU-Auslastung erhöhen und die Leistung der Speicher-Engine verbessern können.
Page Cleaner Thread wird verwendet, um den Aktualisierungsvorgang für schmutzige Seiten im Master-Thread zu ersetzen. Sein Zweck besteht darin, die Arbeit des ursprünglichen Master-Threads und das Blockieren von Benutzerabfrage-Threads zu reduzieren und die Leistung der InnoDB-Speicher-Engine weiter verbessern.
Speicher
InnoDB-Speicher-Engine-Speicherstruktur
InnoDB-Speicher Die Engine basiert auf Festplattenspeicher und verwaltet die Datensätze in Seiten. Aufgrund der Kluft zwischen CPU-Geschwindigkeit und Festplattengeschwindigkeit verwenden festplattenbasierte Datenbanksysteme jedoch häufig Pufferpooldatensätze, um die Gesamtleistung der Datenbank zu verbessern.
Der Pufferpool nutzt tatsächlich die Geschwindigkeit des Speichers, um die Auswirkungen einer langsamen Festplattengeschwindigkeit auf die Datenbankleistung auszugleichen. Wenn die Datenbank einen Lesevorgang ausführt, wird die Seite auf der Festplatte zunächst in den Pufferpool gestellt. Beim nächsten Lesen derselben Seite werden die Seitendaten zunächst aus dem Pufferpool abgerufen, um als Cache zu fungieren.
Der Datenänderungsvorgang ändert zunächst die Seitendaten im Pufferpool und schreibt sie dann mithilfe eines Mechanismus namens Checkpoint auf die Festplatte.
Die Größe des Pufferpools wirkt sich direkt auf die Gesamtleistung der Datenbank aus. Für die InnoDB-Speicher-Engine wird die Pufferpoolkonfiguration über den Parameter innodb_buffer_pool_size festgelegt. Verwenden Sie den Befehl SHOW VARIABLES LIKE 'innodb_buffer_pool_size'
, um die Pufferpoolkonfiguration anzuzeigen:
mysql> SHOW VARIABLES LIKE 'innodb_buffer_pool_size' \G *************************** 1. row *************************** Variable_name: innodb_buffer_pool_size Value: 134217728 1 row in set (0.01 sec)
Die im Pufferpool zwischengespeicherten Datenseitentypen sind: Indexseiten, Rückgängig-Seiten, Einfügepuffer, adaptive Hash-Indizes, InnoDB-Sperrinformationen, Daten Wörterbuchinformationen usw., Indexseiten und Datenseiten machen einen großen Teil des Pufferpools aus.
Wenn die Seitendaten im Pufferpool neuer als die Festplatte sind, müssen die neuen Daten auf die Festplatte geleert werden. InnoDB verwendet die Write-Ahead-Log-Strategie, um Daten zu aktualisieren. Das heißt, wenn eine Transaktion übermittelt wird, wird zuerst der Redo-Log-Puffer in einer bestimmten Häufigkeit in die Reset-Log-Datei geschrieben und dann die fehlerhaften Seiten wird gemäß dem Checkpoint-Mechanismus auf die Festplatte geschrieben.
Der Redo-Log-Puffer muss nicht sehr groß eingestellt werden, 8M kann die meisten Anwendungsszenarien erfüllen. Das Redo-Log unterstützt die folgenden drei Situationen, um eine Aktualisierung auszulösen:
Master Thread leert den Redo-Log-Puffer jede Sekunde in die Redo-Log-Datei
Der Redo-Log-Puffer wird jedes Mal, wenn eine Transaktion festgeschrieben wird, in die Redo-Log-Datei geleert.
Wenn der verbleibende Speicherplatz im Redo-Log-Pufferpool weniger als 1/2 beträgt, wird der Redo-Log-Puffer wird in die Redo-Log-Datei geschrieben. Erstellen Sie Protokolldateien durch einen Prozess namens Speicher, der auf Heap-Art ausgeführt wird. Bei der Zuweisung des Speichers einiger Datenstrukturen selbst ist eine Anwendung aus einem zusätzlichen Speicherpool erforderlich. Wenn der Speicher in diesem Bereich nicht ausreicht, wird er aus dem Pufferpool zugewiesen.
Absichtssperre
Lückensperre
Auto-Inkrement-Sperre
InnoDB Die Engine implementiert zwei Standardsperren auf Zeilenebene, gemeinsame (S) Sperren und exklusive (X) Sperren. Eine gemeinsame Sperre ermöglicht einer Transaktion, die die Sperre hält, das Lesen einer Datenzeile, und eine exklusive Sperre ermöglicht einer Transaktion, in eine Datensatzzeile zu schreiben.
Wenn eine Transaktion eine gemeinsame Sperre hält, können andere Transaktionen weiterhin die gemeinsame Sperre dieses Zeilendatensatzes erhalten, jedoch nicht die exklusive Sperre dieses Zeilendatensatzes. Wenn eine Transaktion eine exklusive Sperre für eine Zeile erhält, können andere Transaktionen keine gemeinsamen Sperren und exklusiven Sperren für diese Zeile mehr erwerben.
In InnoDB ist die Absichtssperre eine Sperre auf Tabellenebene, die in gemeinsame Sperre und exklusive Sperre unterteilt ist:
Absicht geteilt Sperre: Im Begriff, die gemeinsame Sperre einer bestimmten Zeile zu erwerben
Absicht exklusive Sperre: Im Begriff, die exklusive Sperre einer bestimmten Zeile zu erwerben
Die Transaktion wird aktiviert. Bevor Sie eine gemeinsame Sperre/exklusive Sperre erhalten, müssen Sie zunächst eine gemeinsame oder exklusive Sperre erwerben. Absichtssperren blockieren keine anderen Vorgänge in der Tabelle. Sie teilen anderen Transaktionen lediglich mit, dass sie eine gemeinsame Sperre oder eine exklusive Sperre erwerben werden eine bestimmte Reihe.
Datensatz ist eine Art Sperre, die auf den Index wirkt. Sie sperrt den Index eines bestimmten Datensatzes und nicht den Datensatz selbst. Wenn die aktuelle Tabelle keinen Index hat. InnoDB erstellt dafür einen versteckten Clustered-Index und Record Locks sperrt den versteckten Clustered-Index.
Lückensperre und Datensatzsperre wirken sich auch auf den Index aus. Der Unterschied besteht darin, dass die Datensatzsperre nur auf einen Indexdatensatz wirkt und die Lückensperre einen Bereich von Indizes sperren kann. Die einzige Funktion von Gap-Sperren in InnoDB besteht darin, zu verhindern, dass andere Transaktionen Vorgänge einfügen, wodurch Phantom-Lesevorgänge verhindert werden.
Die Auto-Inkrement-Sperre ist eine spezielle Sperre auf Tabellenebene, die nur für Einfügevorgänge mit automatisch inkrementierten Spalten gilt. Wenn eine Transaktion ein Datenelement einfügt, muss jede andere Transaktion warten, bis die gesamte Transaktion den Einfügevorgang abgeschlossen hat, und dann die Sperre erwerben, um den Einfügevorgang auszuführen.
Transaktion
ACID
Transaktion ist das wichtigste Merkmal der Datenbank als OLTP. Wenn wir über Transaktionen sprechen, müssen wir die vier Grundfunktionen erwähnen Merkmale von ACID:
Atomizität: die kleinste Arbeitseinheit einer Transaktion, entweder alle erfolgreich oder alle fehlgeschlagen
Konsistenz: der Anfang und das Ende einer Transaktion Danach wird die Integrität der Datenbank nicht zerstört
Isolation: Verschiedene Transaktionen beeinflussen sich gegenseitig nicht. Die vier Isolationsstufen sind RU (read uncommitted), RC (Read festgeschrieben), RR (wiederholbares Lesen), SERIALIZABLE (Serialisierung)
Dauerhaftigkeit (Durability): Nach dem Festschreiben der Transaktion ist die Änderung der Daten dauerhaft, auch wenn ein Systemausfall nicht auftritt verloren gehen
Die Atomizität, Persistenz und Konsistenz von InnoDB werden hauptsächlich durch die Mechanismen Redo Log, Undo Log und Force Log at Commit erreicht. Redo Log wird zur Datenwiederherstellung im Falle eines Absturzes verwendet, Undo Log wird zum Rückgängigmachen der Auswirkungen von Transaktionen verwendet und kann auch für die Kontrolle mehrerer Versionen verwendet werden. Der Force Log at Commit-Mechanismus stellt sicher, dass das Redo-Log nach dem Commit der Transaktion bestehen bleibt. Die Isolation wird durch Sperren und MVCC gewährleistet.
In MySQL gibt es 4 Isolationsstufen für Transaktionen:
Read Uncommitted Read
Read Committed Read Committed
Repeatable Read Repeatable Read
Serialisierbar
Bevor wir die vier Isolationsstufen verstehen, müssen wir drei weitere Begriffe verstehen:
Dirty Read
Transaktion a liest die nicht festgeschriebenen Daten der Transaktion b, aber Transaktion b führt aus irgendeinem Grund einen Rollback-Vorgang aus. Auf diese Weise sind die von Transaktion a gelesenen Daten nicht verfügbar, was zu einigen abnormalen Ergebnissen führt.
Nicht wiederholbares Lesen
Bestimmte Daten werden während eines Transaktionszyklus mehrmals abgefragt und die Daten werden in dem aktualisiert bzw. aktualisiert b Transaktionslöschvorgang. Dann können die Ergebnisse jeder Abfrage für Transaktion a unterschiedlich sein.
Phantom-Lesen
Das Ergebnis des Phantom-Lesens ist tatsächlich das gleiche wie beim nicht wiederholbaren Lesen. Der Unterschied besteht darin, dass es sich um ein nicht wiederholbares Lesen handelt hauptsächlich für andere Die Transaktion führt Bearbeitungs- (Aktualisierungs-) und Löschvorgänge (Löschvorgänge) durch. Das Phantomlesen dient hauptsächlich dem Einfügevorgang. Das heißt, innerhalb des Lebenszyklus einer Transaktion werden neu eingefügte Daten einer anderen Transaktion abgefragt.
Nicht festgeschriebenes Lesen In diesem Fall kann eine Transaktion a die nicht festgeschriebenen Daten einer anderen Transaktion b sehen. Wenn Transaktion b zu diesem Zeitpunkt zurückgesetzt wird, erhält sie dann sind schmutzige Daten, was die Bedeutung von schmutzigem Lesen bedeutet.
Diese Isolationsstufe wird in MySQL InnoDB im Allgemeinen nicht empfohlen.
Committed lesen: Alle von einer Transaktion vom Anfang bis zum Commit vorgenommenen Änderungen sind für andere Transaktionen unsichtbar. Das Dirty-Read-Problem ist gelöst, aber das Phantom-Read-Phänomen existiert.
Wiederholbares Lesen, diese Ebene stellt sicher, dass die Ergebnisse des mehrmaligen Lesens desselben Datensatzes in derselben Transaktion konsistent sind, und löst sowohl Phantom-Lesevorgänge als auch nicht wiederholbare Lesevorgänge in der InnoDB-Speicher-Engine Lesen Sie die Frage.
Die InnoDB-Engine löst das Problem von Phantom-Lesevorgängen durch die Verwendung von Next-Key Lock
. Next-Key Lock
ist eine Kombination aus Zeilensperre und Lückensperre. Wenn InnoDB den Indexdatensatz scannt, fügt es zunächst eine Zeilensperre (Record Lock) zum Indexdatensatz und dann eine Lückensperre (Gap Lock) zu den Lücken hinzu beiden Seiten des Indexdatensatzes. Nach dem Hinzufügen der Lückensperre können andere Transaktionen keine Datensätze in dieser Lücke ändern oder einfügen.
Serialisierbar ist die höchste Isolationsstufe. Es vermeidet das Problem von Phantom-Lesevorgängen, indem es die serielle Ausführung von Transaktionen erzwingt sind gesperrt, daher kann es zu vielen Zeitüberschreitungen und Sperrkonfliktproblemen kommen, sodass die Parallelität stark abnimmt und die Verwendung in MySQL InnoDB nicht empfohlen wird.
BEGIN, ARBEITEN BEGINNEN, TRANSAKTION STARTEN
Durch die Ausführung des BEGIN-Befehls wird keine neue Transaktion geöffnet Auf der Engine-Ebene setzt eine Transaktion lediglich eine Markierung für den aktuellen Thread und stellt eine explizit geöffnete Transaktion dar.
TRANSAKTION NUR LESEN STARTEN
Wenn MySQL Server datenverändernde SQL-Transaktionen empfängt, lehnt er diese direkt ab Änderung und gibt einen Fehler zurück. Ich werde die Engine-Ebene für diesen Fehler nicht eingeben.
TRANSAKTION STARTEN, LESEN UND SCHREIBEN
Ermöglicht dem Superuser das Starten einer Lese-/Schreibtransaktion, wenn der schreibgeschützte Status des aktuellen Threads lautet WAHR.
TRANSAKTION MIT KONSISTENTEM SNAPSHOT STARTEN
Durch das Öffnen einer Transaktion wird die Engine-Ebene betreten und ein readview
geöffnet. Dieser Vorgang ist nur unter der RR-Isolationsstufe gültig, andernfalls wird ein Fehler gemeldet.
zeichnet das entsprechende Rückgängig-Protokoll auf, wenn die Daten geändert werden. Wenn die Transaktion fehlschlägt oder rückgängig gemacht wird, können Sie das aufgezeichnete Rückgängig-Protokoll zum Zurücksetzen verwenden. Das Rückgängig-Protokoll ist ein logisches Protokoll, das das Datenbild vor Änderungen aufzeichnet. Wenn während der Änderung gleichzeitig die aktuellen Daten gelesen werden müssen, können die in dieser Zeile aufgezeichneten Daten der vorherigen Version anhand der Versionsinformationen analysiert werden. Darüber hinaus generiert das Rückgängig-Protokoll auch Redo-Protokolle, da das Rückgängig-Protokoll auch einen Persistenzschutz erfordert.
Verwenden Sie den globalen Transaktions-ID-Generator, um Transaktion NO zu generieren, und fügen Sie den aktuell verbundenen Transaktionszeiger (trx_t
) zur globalen Commit-Transaktionsliste hinzu ( trx_serial_list
) in
Markieren Sie „Rückgängig“ Wenn diese Transaktion nur eine UndoPage verwendet und die Nutzung weniger als 3/4 Seite beträgt, markieren Sie diese Seite als TRX_UNDO_CACHED
zufrieden und wenn es insert undo
ist, wird es als TRX_UNDO_TO_FREE
markiert, andernfalls, wenn Rückgängigmachen ein Update-Rückgängigmachen ist, wird es als TRX_UNDO_TO_PURGE
markiert. Mit TRX_UNDO_CACHED
markierte Rückgängigmachungen werden von der Engine recycelt.
Fügen Sie update undo
in das undo segment
von history list
ein und erhöhen Sie rseg_history_len
(global). Aktualisieren Sie gleichzeitig TRX_UNDO_TRX_NO
auf der Seite, wenn die Daten gelöscht werden, setzen Sie delete_mark
zurück und löschen Sie undate undo
aus update_undo_list
, wenn es als und dann zur TRX_UNDO_CACHED
Warteschlangeupdate_undo_cached
hinzugefügt (das Rückgängigmachen/Wiederherstellen des Protokolls wird in den öffentlichen Puffer geschrieben). . Selbst wenn es zu diesem Zeitpunkt abstürzt, kann garantiert werden, dass die Transaktion nach dem Neustart übermittelt wird. Als nächstes müssen Sie den Speicherdatenstatus (mtr_commit
) aktualisierentrx_commit_in_memory
aus der globalen readview
verknüpften Liste entfernen und dann zurücksetzen readview
Die Informationen in der Struktur reichen aus. Eine Lese-/Schreibtransaktion muss zunächst den Transaktionsstatus auf trx_t
setzen, alle Zeilensperren aufheben und TRX_STATE_COMMITTED_IN_MEMORY
aus trx_t
und rw_trx_list
aus der globalen verknüpften Liste readview
entfernen. Wenn es readview
gibt, entfernen Sie es hier. Wenn es insert undo
gibt, aktivieren Sie den Purge-Thread, um den Müll zu bereinigen. Setzen Sie schließlich die Informationen in update undo
zurück, um die Verwendung der nächsten Transaktion zu erleichtern trx_t
, und beginnen Sie mit diesem Rückgängigmachen des Rollbacks update undo
insert undo
ist, löschen Sie den Clustered-Index und den Sekundärindex direkt update undo
Wenn alle Rückgängig-Vorgänge rückgängig gemacht wurden oder auf den angegebenen Rückgängig-Vorgang zurückgesetzt wurden, halten Sie an und löschen Sie das Rückgängig-Protokoll
Index
Die InnoDB-Engine verwendet den B+-Baum als Indexstruktur. Das Datenfeld des Blattknotens des Primärschlüsselindex speichert die vollständigen Felddaten und der Blattknoten des Nicht-Primärschlüsselindex speichert die Wertdaten, auf die verwiesen wird zum Primärschlüssel.
Das obige Bild ist ein schematisches Diagramm des InnoDB-Hauptindex (auch eine Datendatei). Sie können sehen, dass die Blattknoten vollständige Datensätze enthalten ein Clustered-Index. Da die Datendateien von InnoDB selbst nach Primärschlüssel aggregiert werden, erfordert InnoDB, dass die Tabelle über einen Primärschlüssel verfügt. Wenn dies nicht explizit angegeben ist, wählt das MySQL-System automatisch eine Spalte aus, die den Datensatz eindeutig identifizieren kann Wenn die Spalte nicht vorhanden ist, generiert MySQL automatisch ein implizites Feld als Primärschlüssel für die InnoDB-Tabelle. Die Länge dieses Felds beträgt 6 Byte und der Typ ist lang.
Das Hilfsindexdatenfeld von InnoDB speichert den Wert des Primärschlüssels des entsprechenden Datensatzes anstelle der Adresse. Mit anderen Worten: Alle Sekundärindizes in InnoDB verweisen auf den Primärschlüssel als Datenfeld. Durch die Implementierung des Clustered-Index ist die Suche nach Primärschlüssel sehr effizient. Bei der Suche nach Hilfsindizes muss der Index jedoch zweimal abgerufen werden: Rufen Sie zuerst den Hilfsindex ab, um den Primärschlüssel zu erhalten, und verwenden Sie dann den Primärschlüssel, um die Datensätze im Primärschlüssel abzurufen Index.
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die InnoDB-Speicher-Engine in MySQL (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!