|
|
Die beiden oben genannten Situationen können auftreten, wenn mehrere Transaktionen gleichzeitig mit einem Datenelement ausgeführt werden. Der Vorgang einer bestimmten Transaktion kann überschrieben werden, was zu Datenverlust führt.
LBCC behebt Datenverlust
LBCC, Lock Based Concurrency Control.
Wenn die aktuelle Transaktion die Daten ändern muss, wird sie mithilfe des Sperrmechanismus gesperrt. Nur eine Transaktion darf die aktuellen Daten gleichzeitig ändern, und andere Transaktionen müssen warten, bis die Sperre aufgehoben wird bevor sie operieren können.
MVCC behebt Datenverlust
MVCC, Multi-Version-Parallelitätskontrolle, Multi-Version-Parallelitätskontrolle.
Verwenden Sie die Version, um Datenprobleme bei Parallelität zu kontrollieren. Wenn Transaktion B mit der Änderung des Kontos beginnt und die Transaktion nicht übermittelt wird und Transaktion A den Kontostand lesen muss, wird der Kontostand vor dem Änderungsvorgang von Transaktion B gelesen . Daten kopieren, aber wenn Transaktion A die Kontostanddaten ändern muss, muss sie warten, bis Transaktion B die Transaktion festschreibt.
MVCC ermöglicht das Lesen der Datenbank, ohne Daten zu sperren, und normale SELECT-Anfragen werden nicht gesperrt, was die gleichzeitige Verarbeitungsfähigkeit der Datenbank verbessert. Mit Hilfe von MVCC kann die Datenbank Isolationsstufen wie READ COMMITTED und REPEATABLE READ implementieren. Benutzer können die vorherigen oder früheren historischen Versionen der aktuellen Daten anzeigen und so die I-Funktion (Isolation) in ACID sicherstellen.
MVCC-Implementierungslogik von InnoDB
Die von der InnoDB-Speicher-Engine gespeicherten MVCC-Daten
MVCC von InnoDB wird implementiert, indem zwei versteckte Spalten hinter jeder Datensatzzeile gespeichert werden. Eine Transaktions-ID (DB_TRX_ID), die die Zeile speichert, und ein Rollback-Zeiger (DB_ROLL_PT), der die Zeile speichert. Jedes Mal, wenn eine neue Transaktion gestartet wird, wird automatisch eine neue Transaktions-ID erhöht. Zu Beginn der Transaktion wird die Transaktions-ID in die von der aktuellen Transaktion betroffene Zeile eingefügt. Bei der Abfrage muss die aktuelle Transaktions-ID mit der in jeder Zeile aufgezeichneten Transaktions-ID verglichen werden.
Werfen wir einen Blick darauf, wie MVCC unter der Isolationsstufe REPEATABLE READ funktioniert.
SELECT
InnoDB prüft jeden Zeilendatensatz gemäß den folgenden zwei Bedingungen:
InnoDB sucht nur nach Datenzeilen, deren Version älter als die aktuelle Transaktionsversion ist (d. h. die Transaktionsnummer der Zeile). kleiner oder gleich der aktuellen Transaktionsversionsnummer) wird dadurch sichergestellt, dass die von der Transaktion gelesenen Zeilen entweder bereits vor dem Start der Transaktion vorhanden sind oder von der Transaktion selbst eingefügt oder geändert wurden.
Die gelöschten Zeilen müssen anhand der Transaktions-ID und der Statusversion vor dem Lesen der Transaktion beurteilt werden. Nur Datensätze, die die beiden oben genannten Bedingungen erfüllen, können als Abfrageergebnisse zurückgegeben werden.
INSERT
InnoDB speichert die aktuelle Transaktionsnummer als Zeilenversionsnummer für jede neu eingefügte Zeile.
DELETE
InnoDB speichert die aktuelle Transaktionsnummer als Zeilenlöschungsidentifikation für jede gelöschte Zeile.
UPDATE
InnoDB fügt eine neue Zeile mit Datensätzen ein, speichert die aktuelle Transaktionsnummer als Zeilenversionsnummer und speichert die aktuelle Transaktionsnummer in der ursprünglichen Zeile als Zeilenlöschungskennung.
Speichern Sie diese beiden zusätzlichen Transaktionsnummern, damit die meisten Lesevorgänge ohne Sperrung durchgeführt werden können. Dieses Design macht den Datenlesevorgang sehr einfach, die Leistung ist sehr gut und es stellt außerdem sicher, dass nur Zeilen gelesen werden, die den Standards entsprechen. Die Nachteile bestehen darin, dass jede Datensatzzeile zusätzlichen Speicherplatz, mehr Zeilenprüfung und einige zusätzliche Wartungsarbeiten erfordert.
MVCC funktioniert nur unter zwei Isolationsstufen: REPEATABLE READ und READ COMMITIED. Die anderen beiden Isolationsstufen sind nicht mit MVCC kompatibel, da READ UNCOMMITIED immer die neueste Datenzeile liest, nicht die Datenzeile, die der aktuellen Transaktionsversion entspricht. SERIALIZABLE sperrt alle gelesenen Zeilen.
Die Implementierung von MVCC in MySQL basiert auf dem Rückgängigmachen des Protokolls und der Leseansicht.
Rückgängig-Protokoll
Je nach unterschiedlichem Verhalten ist das Rückgängig-Protokoll in zwei Typen unterteilt: Rückgängig-Protokoll einfügen und Rückgängig-Protokoll aktualisieren
Einfügen. Rückgängig machen erzeugt während der Vorgangsprotokoll, da der Einfügungsvorgangsdatensatz nur für die aktuelle Transaktion selbst gilt und für andere Transaktionen nicht sichtbar ist, sodass das Einfüge-Rückgängig-Protokoll direkt nach dem Absenden der Transaktion gelöscht werden kann, ohne dass ein Löschvorgang erforderlich ist.
Die Hauptaufgabe der Bereinigung besteht darin, die Daten zu löschen, die in der Datenbank als „del“ markiert wurden. Darüber hinaus werden auch Rückgängig-Seiten stapelweise recycelt.
Der Anfangszustand der Daten beim Einfügen der Datenbank:
-
Update-Rückgängig-Protokoll:
Update oder Das während des Löschvorgangs generierte Rückgängig-Protokoll. Da es sich auf vorhandene Datensätze auswirkt, kann das Update-Rückgängig-Protokoll zur Bereitstellung des MVCC-Mechanismus nicht gelöscht werden, wenn die Transaktion übermittelt wird. Stattdessen wird es bei der Übermittlung der Transaktion in die Verlaufsliste aufgenommen und wartet auf die Ausführung des Bereinigungsthreads Der letzte Löschvorgang.
Wenn die Daten zum ersten Mal geändert werden:
Wenn eine andere Transaktion die aktuellen Daten zum zweiten Mal ändert:
Um sicherzustellen, dass Transaktionen beim Schreiben ihrer jeweiligen Rückgängig-Protokolle nicht in Konflikt geraten Gleichzeitige Vorgänge, InnoDB Verwenden Sie Rollback-Segmente, um das gleichzeitige Schreiben und die Persistenz von Rückgängig-Protokollen aufrechtzuerhalten. Das Rollback-Segment ist eigentlich eine Möglichkeit, Undo-Dateien zu organisieren.
ReadView
Für die Isolationsstufe RU(READ UNCOMMITTED) können alle Transaktionen den neuesten Wert der Datenbank direkt lesen, und für die Isolationsstufe SERIALIZABLE werden alle Anforderungen gesperrt und synchron ausgeführt. In diesen beiden Fällen ist es also nicht erforderlich, die Versionskontrolle von Read View zu verwenden.
Für RC(READ COMMITTED) und RR(REPEATABLE READ) wird die Implementierung der Isolationsstufe durch die obige Versionskontrolle abgeschlossen. Die Kernverarbeitungslogik unter den beiden Isolationskategorien besteht darin, zu bestimmen, welche Version unter allen Versionen für die aktuelle Transaktion sichtbar ist. Um dieses Problem zu lösen, hat InnoDB ein ReadView-Design hinzugefügt, das hauptsächlich die anderen aktiven Lese- und Schreibtransaktionen im aktuellen System enthält und ihre Transaktions-IDs in eine Liste einfügt . Die Beurteilungslogik dafür, ob die Versionskettendaten während der Abfrage sichtbar sind:
Wenn der trx_id-Attributwert der abgerufenen Version kleiner als die kleinste Transaktions-ID in der m_ids-Liste ist, bedeutet dies, dass die Transaktion diese Version generiert hat wurde übermittelt, bevor die ReadView generiert wurde, sodass auf diese Version von der aktuellen Transaktion zugegriffen werden kann.
-
Wenn der Wert des trx_id-Attributs der Version, auf die zugegriffen wird, größer ist als die größte Transaktions-ID in der m_ids-Liste, bedeutet dies, dass die Transaktion, die diese Version generiert hat, nach der ReadView-Generierung generiert wurde, sodass auf diese Version nicht zugegriffen werden kann durch die aktuelle Transaktion.
-
Wenn der trx_id-Attributwert der aufgerufenen Version zwischen der größten Transaktions-ID und der kleinsten Transaktions-ID in der m_ids-Liste liegt, müssen Sie feststellen, ob der trx_id-Attributwert in der m_ids-Liste enthalten ist bedeutet, dass beim Erstellen von ReadView die Transaktion dieser Version noch aktiv ist und auf diese Version nicht zugegriffen werden kann. Andernfalls bedeutet dies, dass die Transaktion, die diese Version beim Erstellen von ReadView generiert hat, festgeschrieben wurde und diese Version verfügbar ist zugegriffen.
Zum Beispiel:
ReadView unter der Isolationsstufe READ COMMITTED
Generieren Sie jedes Mal eine ReadView (m_ids-Liste), bevor Sie Daten lesen
Zeit
Transaktion 777 |
Transaktion 888 |
Transaktion 999 |
|
T1
beginnen; |
|
|
|
beginnen; | beginnen;
|
T3 |
UPDATE user SET name = 'CR7' WHERE id = 1; |
|
|
| T4
|
... |
|
| T. 5
UPDATE Benutzer SET name = 'Messi ' WHERE id = 1; |
| SELECT * FROM user where id = 1; |
T6 |
commit; |
|
|
| T7. |
UPDATE Benutzer SET Name = 'Neymar' WHERE id = 1; |
|
| T8
|
|
SELECT * FROM user where id = 1;
|
T9 |
|
UPDATE user SET name = 'Dybala ' WHERE id = 1; |
|
| T10
|
commit; |
|
| T11
|
|
SELECT * FROM user where id = 1;
|
Hier ist eine Analyse der ReadView in der obigen Situation
Die SELECT-Anweisung zum Zeitpunkt T5:
Die Versionskette zum aktuellen Zeitpunkt:
Die SELECT-Anweisung wird zu diesem Zeitpunkt ausgeführt und die Versionskette von Die aktuellen Daten sind wie oben, da die aktuelle Transaktion 777 und die Transaktion 888 nicht übermittelt wurden, sodass die Liste der ReadView der zu diesem Zeitpunkt aktiven Transaktionen m_ids: [777, 888] ist, sodass die Abfrageanweisung darauf basieren wird die größten Versionsdaten in der aktuellen Versionskette, die kleiner als m_ids sind. Das heißt, die Abfrage ist Mbappe.
Die SELECT-Anweisung zum Zeitpunkt T8:
Die Versionskettensituation zum aktuellen Zeitpunkt:
Die SELECT-Anweisung wird zu diesem Zeitpunkt ausgeführt, und die Versionskette der aktuellen Daten ist wie oben, da die aktuelle Transaktion erfolgt 777 wurde übermittelt und Transaktion 888 wurde nicht übermittelt, sodass die Liste der derzeit aktiven Transaktionen m_ids: [888] ist, sodass die Abfrageanweisung auf den größten Versionsdaten in der aktuellen Versionskette basiert Das sind weniger als m_ids, das heißt, Messi wird abgefragt.
SELECT-Anweisung zum Zeitpunkt T11:
Versionsketteninformationen zum aktuellen Zeitpunkt:
Zu diesem Zeitpunkt wird die SELECT-Anweisung ausgeführt und die Versionskette der aktuellen Daten ist wie oben, da die aktuelle Transaktion erfolgt 777 und Transaktion 888 wurden übermittelt. Daher ist die ReadView-Liste für aktive Transaktionen zu diesem Zeitpunkt leer, sodass die Abfrageanweisung direkt die neuesten Daten der aktuellen Datenbank abfragt, dh Dybala.
Zusammenfassung: Eine Transaktion mit der Isolationsstufe READ COMMITTED generiert zu Beginn jeder Abfrage eine unabhängige ReadView.
ReadView unter der Isolationsstufe REPEATABLE READ
Erzeugt eine ReadView (m_ids-Liste), wenn die Daten zum ersten Mal nach Beginn der Transaktion gelesen werden
Zeit |
Transaktion 777 | Transaktion 888. Transaktion 999 |
beginnen;beginnen; |
T3
UPDATE-Benutzer SET name = 'CR7' WHERE id = 1; |
|
|
|
T4
|
... |
|
|
T5 | UPDATE. Benutzer SET-Name = 'Messi' WHERE id = 1; |
| SELECT * FROM user where id = 1;
|
T6
commit; |
|
|
|
T7
| | UPDATE Benutzer SET name = ' Neymar' WHERE id = 1;
|
|
T8 |
|
|
SELECT * FROM user where id = 1;
|
T9 |
| UP DATE user SET name = 'Dybala ' WHERE id =. 1; |
|
T10 |
| commit;
|
|
T11 |
|
| ECT * FROM user where id = 1;
|
Zeitpunkt SELECT-Anweisung im Fall von T5: |
Aktuelle Versionskette:
|
Eine ReadView wird generiert, wenn die SELECT-Anweisung aktuell ausgeführt wird. Zu diesem Zeitpunkt ist der Inhalt von | m_ids: [777,888], also Die gemäß der sichtbaren Version von ReadView abgefragten Daten sind Mbappe.
|
SELECT-Anweisung zum Zeitpunkt T8:
Aktuelle Versionskette: |
In der aktuellen Transaktion 999 zu diesem Zeitpunkt. Da ReadView zum Zeitpunkt T5 generiert wurde, wird ReadView in der aktuellen Transaktion nur einmal generiert, sodass die | m_ids bei T5 zu diesem Zeitpunkt noch verwendet werden: [777.999], sodass die Abfragedaten zu diesem Zeitpunkt immer noch Mbappe sind.
|
SELECT-Anweisung zum Zeitpunkt T11: |
Aktuelle Versionskette:
Die Situation zu diesem Zeitpunkt ist genau die gleiche wie bei T8. Da ReadView zum Zeitpunkt T5 generiert wurde, wird ReadView in der aktuellen Transaktion nur einmal generiert, sodass die m_ids bei T5 zu diesem Zeitpunkt noch verwendet werden: [777.999], sodass die Abfragedaten zu diesem Zeitpunkt immer noch Mbappe sind.
MVCC-Zusammenfassung: Der sogenannte MVCC (Multi-Version Concurrency Control, Multi-Version-Parallelitätskontrolle) bezieht sich auf die Verwendung der beiden Isolationsstufen READ COMMITTD und REPEATABLE READ zur Ausführung gewöhnlicher Transaktionen. Bei der SEELCT-Operation handelt es sich um den Prozess des Zugriffs auf die aufgezeichnete Versionskette, der es ermöglicht, Vorgänge verschiedener Transaktionen gleichzeitig auszuführen und so die Systemleistung zu verbessern. Empfohlenes Lernen: MySQL-Video-Tutorial
|