Analyse des zugrunde liegenden Prinzips der MySQL-Mehrversions-Parallelitätskontrolle MVCC

Analyse des zugrunde liegenden Prinzips der MySQL-Mehrversions-Parallelitätskontrolle MVCC

1 Probleme bei der Transaktions-Parallelität

1.1 Schmutziges Lesen

Wenn eine Transaktion Daten liest, die geändert, aber nicht von einer anderen Transaktion festgeschrieben wurden, wird dies als „Dirty Read“ bezeichnet.

1.2 Nicht wiederholbares Lesen

Wenn derselbe Datensatz innerhalb einer Transaktion zweimal abgerufen wird und die erzielten Ergebnisse zweimal unterschiedlich sind, wird dieses Phänomen als nicht wiederholbarer Lesevorgang bezeichnet.

1.3 Phantom-Lesevorgänge

Wenn eine Transaktion zweimal (oder mehrmals) mit derselben Abfragebedingung abfragt und die Anzahl der gefundenen Einträge inkonsistent ist, wird dies als Phantomlesen bezeichnet.

2 Isolationsebenen

Wir haben mehrere Probleme vorgestellt, die bei der Ausführung gleichzeitiger Transaktionen auftreten können. Diese Probleme haben auch unterschiedliche Prioritäten. Wir ordnen diese Probleme nach ihrer Schwere:

Dirty Read > Nicht wiederholbares Lesen > Phantomlesen

Der SQL-Standard legt fest, dass gleichzeitige Transaktionen bei unterschiedlichen Isolationsebenen unterschiedliche Schweregrade aufweisen können.

Der konkrete Sachverhalt stellt sich wie folgt dar:

  • LESEN UNCOMMITTED: Lesen ohne Commit.
  • LESEN VERPFLICHTET: Lesen verpflichtet.
  • WIEDERHOLBARES LESEN: Wiederholbares Lesen.
  • SERIALIZABLE: Serialisierbar

Der SQL-Standard legt fest, dass bei verschiedenen Isolationsstufen bei gleichzeitigen Transaktionen Probleme unterschiedlicher Schwere auftreten können:

  • Auf der Isolationsebene READ UNCOMMITTED können Dirty Reads, nicht wiederholbare Lesevorgänge und Phantom-Lesevorgänge auftreten.
  • Auf der Isolationsebene READ COMMITTED können nicht wiederholbare Lesevorgänge und Phantomlesevorgänge auftreten, aber keine Dirty Reads.
  • Auf der Isolationsebene „REPEATABLE READ“ können Phantomlesevorgänge stattfinden, „Dirty Reads“ und nicht wiederholbare Lesevorgänge sind jedoch nicht möglich.
  • Auf der Isolationsebene SERIALIZABLE können verschiedene Probleme nicht auftreten.

3 Versionskette

Wir wissen, dass der Clustered-Indexdatensatz einer Tabelle, die die Speicher-Engine InnoDB verwendet, zwei notwendige versteckte Spalten enthält (row_id ist nicht notwendig und die Spalte row_id wird nicht eingeschlossen, wenn die von uns erstellte Tabelle einen Primärschlüssel oder einen von NULL verschiedenen UNIQUE-Schlüssel hat):

trx_id : Jedes Mal, wenn eine Transaktion einen gruppierten Indexdatensatz ändert, wird die Transaktions-ID der Transaktion der ausgeblendeten Spalte trx_id zugewiesen.

roll_pointer : Jedes Mal, wenn ein gruppierter Indexdatensatz geändert wird, wird die alte Version in das Undo-Protokoll geschrieben, und diese ausgeblendete Spalte fungiert als Zeiger, mit dem die Informationen gefunden werden können, bevor der Datensatz geändert wird.

Angenommen, die Transaktions-ID des eingefügten Datensatzes ist 80, sieht das schematische Diagramm des Datensatzes zu diesem Zeitpunkt wie folgt aus:

Angenommen, zwei Transaktionen mit den Transaktions-IDs 100 und 200 führen UPDATE-Operationen für diesen Datensatz aus. Der Operationsablauf ist wie folgt:

TRX 100:

UPDATE t_people SET name = "Guan Yu" WHERE number = 1;
UPDATE t_people SET name = 'Person' WHERE number = 1;

TRX 200:

UPDATE t_people SET name = "Zhao Yun" WHERE number = 1;
UPDATE t_people SET name = "Zhuge Liang" WHERE number = 1;

Bei jeder Änderung eines Datensatzes wird ein Undo-Protokoll aufgezeichnet. Jedes Undo-Protokoll verfügt außerdem über ein roll_pointer-Attribut (das Undo-Protokoll, das der INSERT-Operation entspricht, verfügt nicht über dieses Attribut, da der Datensatz keine frühere Version hat). Diese Undo-Protokolle können zu einer verknüpften Liste verbunden werden, sodass die aktuelle Situation wie in der folgenden Abbildung aussieht:

Nach jeder Aktualisierung des Datensatzes wird der alte Wert in ein Undo-Protokoll eingetragen, selbst wenn es sich um eine alte Version des Datensatzes handelt. Mit zunehmender Anzahl von Aktualisierungen werden alle Versionen durch das Attribut roll_pointer zu einer verknüpften Liste verbunden. Wir nennen diese verknüpfte Liste eine Versionskette, und der Kopfknoten der Versionskette ist der neueste Wert des aktuellen Datensatzes. Darüber hinaus enthält jede Version auch die Transaktions-ID, die der Generation der Version entspricht. Die Versionskette dieses Datensatzes kann dann verwendet werden, um das Verhalten gleichzeitiger Transaktionen zu steuern, die auf denselben Datensatz zugreifen. Dieser Mechanismus wird als多版本并發控制(Mulit-Version Concurrency Control MVCC) bezeichnet.

4 LesenAnzeigen

4.1 ReadView-Definition

InnoDB schlägt ein ReadView-Konzept vor, das hauptsächlich vier wichtige Inhalte umfasst:

  • (1) m_ids: stellt die Transaktions-ID-Liste der aktiven Lese- und Schreibtransaktionen im aktuellen System dar, wenn die ReadView generiert wird.
  • (2) min_trx_id: Gibt die kleinste Transaktions-ID unter den aktiven Lese- und Schreibtransaktionen im aktuellen System an, wenn die ReadView generiert wird, d. h. den Mindestwert in m_ids.
  • (3) max_trx_id: Gibt den ID-Wert an, der beim Generieren eines ReadView der nächsten Transaktion im System zugewiesen werden soll. max_trx_id ist nicht der Maximalwert in m_ids. Transaktions-IDs werden inkrementell zugewiesen. Beispielsweise gibt es drei Transaktionen mit den IDs 1, 2 und 3, und dann wird die Transaktion mit der ID 3 festgeschrieben. Wenn dann eine neue Lesetransaktion ReadView generiert, enthält m_ids 1 und 2, der Wert von min_trx_id ist 1 und der Wert von max_trx_id ist 4.
  • (4) creator_trx_id: Gibt die Transaktions-ID der Transaktion an, die den ReadView generiert hat.

4.2 Zugriffskontrolle

Mit diesem ReadView müssen Sie beim Zugriff auf einen Datensatz nur die folgenden Schritte ausführen, um festzustellen, ob eine Version des Datensatzes sichtbar ist:

  • (1) Wenn der Attributwert „trx_id“ der aufgerufenen Version mit dem Wert „creator_trx_id“ in ReadView übereinstimmt, bedeutet dies, dass die aktuelle Transaktion auf den Datensatz zugreift, den sie geändert hat. Auf die Version kann daher von der aktuellen Transaktion zugegriffen werden.
  • (2) Wenn der Attributwert „trx_id“ der aufgerufenen Version kleiner ist als der Wert „min_trx_id“ in ReadView, bedeutet dies, dass die Transaktion, die diese Version generiert hat, festgeschrieben wurde, bevor die aktuelle Transaktion ReadView generiert hat. Auf diese Version kann daher von der aktuellen Transaktion zugegriffen werden.
  • (3) Wenn der Attributwert trx_id der aufgerufenen Version größer oder gleich dem Wert max_trx_id in ReadView ist, bedeutet dies, dass die Transaktion, die diese Version generiert hat, geöffnet wurde, nachdem die aktuelle Transaktion ReadView generiert hat. Auf diese Version kann daher von der aktuellen Transaktion nicht zugegriffen werden.
  • (4) Wenn der Attributwert trx_id der aufgerufenen Version zwischen min_trx_id und max_trx_id der ReadView liegt (min_trx_id < trx_id < max_trx_id), muss ermittelt werden, ob der Attributwert trx_id in der m_ids-Liste enthalten ist. Wenn dies der Fall ist, bedeutet dies, dass die Transaktion, die die Version beim Erstellen der ReadView generiert hat, noch aktiv ist und auf die Version nicht zugegriffen werden kann. Wenn dies nicht der Fall ist, bedeutet dies, dass die Transaktion, die die Version beim Erstellen der ReadView generiert hat, festgeschrieben wurde und auf die Version zugegriffen werden kann.
  • (5) Wenn eine bestimmte Version der Daten für die aktuelle Transaktion nicht sichtbar ist, folgen Sie der Versionskette, um die nächste Version der Daten zu finden, und bestimmen Sie die Sichtbarkeit weiterhin gemäß den obigen Schritten und so weiter, bis Sie die letzte Version in der Versionskette erreicht haben. Wenn auch die letzte Version nicht sichtbar ist, bedeutet dies, dass der Datensatz für die Transaktion vollständig unsichtbar ist und das Abfrageergebnis den Datensatz nicht enthält.

4.3 Isolation neu betrachtet

Da Sie bei Transaktionen mit der Isolationsebene READ UNCOMMITTED Datensätze lesen können, die durch nicht festgeschriebene Transaktionen geändert wurden, können Sie einfach die neueste Version der Datensätze direkt lesen.

Bei Transaktionen mit der Isolationsebene SERIALIZABLE verwendet InnoDB Sperren für den Zugriff auf Datensätze.

Ein sehr großer Unterschied zwischen den Isolationsebenen READ COMMITTED und REPEATABLE READ in MySQL besteht im Zeitpunkt ihrer Generierung von ReadView.

4.3.1 READ COMMITTED

Lesen übermittelt, vor jedem Datenlesen wird ein ReadView generiert.

Nehmen wir nun an, dass die Ausführung einer Transaktion mit der Isolationsstufe READ COMMITTED beginnt:

Detaillierte Abfrage:

#Transaktion mit Isolationsstufe READ COMMITTED #Transaktion 100 und 200 werden nicht festgeschrieben und der Wert des Spaltennamens ist Liu BeiSELECT name FROM t_people WHERE number = 1;

Der Ausführungsprozess dieses SELECET ist wie folgt:

  • (1) Bei der Ausführung der SELECT-Anweisung wird zunächst eine ReadView erzeugt. Der Inhalt der m_ids-Liste der ReadView ist [100, 200], min_trx_id ist 100, max_trx_id ist 201 und creator_trx_id ist 0.
  • (2) Wählen Sie dann die sichtbaren Datensätze aus der Versionskette aus. Wie aus der Abbildung ersichtlich, lautet der Inhalt der Spalte „Name“ der neuesten Version „Zhuge Liang“. Der trx_id-Wert dieser Version beträgt 200, was in der m_ids-Liste steht und daher die Sichtbarkeitsanforderung nicht erfüllt. (Wenn der Attributwert trx_id der aufgerufenen Version zwischen min_trx_id und max_trx_id von ReadView liegt, muss ermittelt werden, ob der Attributwert trx_id in der Liste m_ids enthalten ist. Wenn dies der Fall ist, bedeutet dies, dass die Transaktion, die die Version beim Erstellen von ReadView generiert hat, noch aktiv ist und auf die Version nicht zugegriffen werden kann; wenn nicht, bedeutet dies, dass die Transaktion, die die Version beim Erstellen von ReadView generiert hat, festgeschrieben wurde und auf die Version zugegriffen werden kann.) Springen Sie gemäß dem roll_pointer zur nächsten Version.
  • (3) Der Inhalt der Spalte „Name“ der nächsten Version von Zhuge Liang ist Zhao Yun. Der trx_id-Wert dieser Version ist ebenfalls 200, was auch in der m_ids-Liste enthalten ist. Daher erfüllt es die Anforderungen nicht und springt weiter zur nächsten Version.
  • (4) Der Inhalt der Spalte „Name“ der nächsten Version von Zhao Yun ist Zhang Fei. Der trx_id-Wert dieser Version ist ebenfalls 100, was auch in der m_ids-Liste enthalten ist. Daher erfüllt es die Anforderungen nicht und springt weiter zur nächsten Version.
  • (5) Der Inhalt der Spalte „Name“ der nächsten Version von Zhang Fei ist Guan Yu. Der trx_id-Wert dieser Version ist ebenfalls 100, was auch in der m_ids-Liste enthalten ist. Daher erfüllt es die Anforderungen nicht und springt weiter zur nächsten Version.
  • (6) Die nächste Version von Guan Yu ist Liu Bei. Der trx_id-Wert dieser Version beträgt 80, was kleiner ist als der min_trx_id-Wert in ReadView, sodass diese Version die Anforderungen erfüllt.

Nicht wiederholbares Lesen: Wenn die Transaktionen 100 und 200 gestartet werden, lautet der gelesene Name Liu Bei. Wenn Transaktion 100 festgeschrieben wird, wird für jeden Lesevorgang eine ReadView erstellt, da die Isolationsstufe der Transaktion auf Lesen festgeschrieben ist. Wenn Transaktion 200 gelesen wird, ist die generierte ReadView m_ids [200]. Zu diesem Zeitpunkt lautet der gemäß der Leseregel gelesene Name Zhang Fei.

# Verwenden Sie die Transaktion BEGIN mit der Isolationsstufe READ COMMITTED;
# SELECE1: Transaktion 100 und 200 wurden nicht übermittelt und der Namenswert ist Liu Bei SELECT name FROM t_people WHERE number = 1; 

# SELECE2: Transaktion 100 ist festgeschrieben, Transaktion 200 ist nicht festgeschrieben. #Transaktionsabfrage für Transaktion 200, der Namenswert ist Zhang Fei und es erfolgt ein nicht wiederholbarer Lesevorgang.
Wählen Sie Name aus Lehrer, wobei Nummer = 1 ist.

4.3.2 WIEDERHOLBARES LESEN

Wiederlesbar, generiert eine ReadView beim ersten Lesen der Daten.

Lösen Sie das Problem des nicht wiederholbaren Lesens: 100 Transaktionen und 200 Transaktionen sind aktiviert und ReadView wird erstellt. m_ids ist [100,200] und der gelesene Name ist Liu Bei. Wenn Transaktion 100 festgeschrieben wird, wird aufgrund der Isolationsstufe für erneut gelesene Transaktionen nur eine ReadView erstellt und m_ids ist immer noch [100,200]. Zu diesem Zeitpunkt ist der gemäß der Leseregel gelesene Name immer noch Liu Bei.

5 Phantom-Lesungen

Wenn eine Transaktion zweimal (oder mehrmals) mit derselben Abfragebedingung abfragt und die Anzahl der gefundenen Einträge inkonsistent ist, wird dies als Phantomlesen bezeichnet.

Die Transaktion T1 auf der Isolationsebene „REPEATABLE READ“ liest zunächst mehrere Datensätze basierend auf einer Suchbedingung, dann fügt die Transaktion T2 einen Datensatz ein, der die entsprechende Suchbedingung erfüllt, und schreibt ihn fest, und anschließend führt die Transaktion T1 eine Abfrage basierend auf derselben Suchbedingung aus. Was wird das Ergebnis sein? Gemäß den Vergleichsregeln in ReadView kann die Transaktion T1 das Commit von T2 nicht sehen, unabhängig davon, ob die Transaktion T2 vor der Transaktion T1 gestartet wird. Allerdings kann MVCC in InnoDB unter der Isolationsebene REPEATABLE READ Phantomlesevorgänge weitgehend vermeiden, anstatt sie vollständig zu verbieten.

#SELECT: Schnappschuss gelesen. Update: wird gerade gelesen.
REPEATABLE READ kann das Phantom-Read-Problem beim Snapshot-Read lösen. Das aktuelle Phantom-Read-Problem kann nicht gelöst werden.

Beispiele:

1 Führen Sie „begin“ und „select *“ aus.

2 Öffnen Sie ein weiteres Fenster, um die Befehle Einfügen, Auswählen und Übernehmen auszuführen.

3 Kehren Sie zum ursprünglichen Fenster zurück, um die Abfrage auszuführen

4 Update durchführen und abschicken

5 Suche

6 Fazit

Aus der obigen Beschreibung können wir ersehen, dass sich das sogenannte MVCC (Multi-Version Concurrency Control) auf den Prozess des Zugriffs auf die Versionskette von Datensätzen bezieht, wenn normale SELECT-Operationen mithilfe von Transaktionen auf den beiden Isolationsebenen READ COMMITTD und REPEATABLE READ ausgeführt werden. Dadurch können Lese-/Schreib- und Schreib-/Leseoperationen verschiedener Transaktionen gleichzeitig ausgeführt werden, wodurch die Systemleistung verbessert wird.

Ein großer Unterschied zwischen den beiden Isolationsebenen READ COMMITTD und REPEATABLE READ ist der Zeitpunkt der Generierung von ReadView. READ COMMITTD generiert vor jedem normalen SELECT-Vorgang einen ReadView, während REPEATABLE READ nur vor dem ersten normalen SELECT-Vorgang einen ReadView generiert und nachfolgende Abfragevorgänge diesen ReadView wiederverwenden, wodurch Phantom-Lesevorgänge grundsätzlich vermieden werden können.

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Grundlegendes Lernprogramm zum MySQL-Abfrage-Cache-Mechanismus
  • Detaillierte Erläuterung der Verwendung des MySQL-Auswahl-Cache-Mechanismus
  • Detaillierte Untersuchung der MySQL-Mehrversions-Parallelitätskontrolle MVCC
  • Implementierung von MySQL Multi-version Concurrency Control MVCC
  • MySQL-Transaktionsisolationsebene und MVCC
  • Tiefgreifendes Verständnis des MVCC- und BufferPool-Cache-Mechanismus in MySQL

<<:  Code zur Implementierung eines einfachen Pfeilsymbols mit Div+CSS in HTML

>>:  Verwenden Sie die Renderfunktion, um hoch skalierbare Komponenten zu kapseln

Artikel empfehlen

SQL-Implementierung von LeetCode (181. Angestellte verdienen mehr als Manager)

[LeetCode] 181.Mitarbeiter verdienen mehr als ihr...

So gehen Sie nach der MySQL-Tabellenpartitionierung problemlos online

Inhaltsverzeichnis Zweck der Tabelle Zum Beispiel...

Detaillierte Erklärung der JavaScript-Ereignisse onblur und onfocus

Auf HTML-Seiten verfügen visuelle Elemente wie Sc...

Eine kurze Analyse der Verwendung von USING und HAVING in MySQL

Dieser Artikel veranschaulicht anhand von Beispie...

So erstellen Sie schnell MySQL Master-Slave mit mysqlreplicate

Einführung Das mysql-utilities-Toolset ist eine S...

So implementieren Sie Datenpersistenz mit dem Vuex-Drittanbieterpaket

Zweck: Ermöglichen Sie die gleichzeitige lokale S...

Natives JS zur Implementierung des Spiels 2048

2048 Minispiel, zu Ihrer Information, der spezifi...

Detaillierte Erläuterung der Redis-Master-Slave-Replikationspraxis mit Docker

Inhaltsverzeichnis 1. Hintergrund 2. Bedienungssc...