Einführung in MySQL-Isolationsebene, Sperre und MVCC

Einführung in MySQL-Isolationsebene, Sperre und MVCC

Ziel dieses Artikels ist es, die Beziehung zwischen diesen Konzepten und ihren Funktionen zu klären. Verstehen Sie den Sperrvorgang und die MVCC-Versionskontrolle jeder SQL-Anweisung, wenn Mysql eine Transaktion öffnet. Um die Diskussion einfach zu halten, werden in diesem Artikel GAP-Sperren (Gap-Sperren, Bereichssperren) ignoriert.

Wir fordern oft eine hohe Parallelität und hohe Verfügbarkeit. Es bedeutet, aus der Perspektive der Qualität und Quantität zu bewerten. Alles kann aus diesen beiden Perspektiven analysiert werden. In der MySQL-Datenbank werden Transaktionen zur Sicherstellung der Qualität und MVCC zur Sicherstellung der Quantität verwendet.

Transaktionen

Wir verwenden Transaktionen, um sicherzustellen, dass die Ergebnisse jeder SQL-Anweisung unseren Erwartungen entsprechend ausgeführt werden. Wir sagen, dass Transaktionen ACID-Eigenschaften haben müssen. Die drei in ACID: Atomizität, Konsistenz und Persistenz beschreiben eigentlich dasselbe und stellen die Zuverlässigkeit der SQL-Ausführungsergebnisse sicher. Isolation ist komplizierter. Sie beschreibt die Leistung der Datenbank in gleichzeitigen Szenarien. Der Grad der Parallelität ist jedoch nicht festgelegt und verschiedene Unternehmen können unterschiedliche Anforderungen haben. Damit sich die Datenbank an verschiedene gleichzeitige Szenarien anpassen kann, haben großartige Leute vier Isolationsstufen definiert: Read Uncommited, Read Committed (RC), Repeatable Read (RR) und Serializable. Mit zunehmender Datenbankisolationsstufe verringert sich die Fähigkeit zur Datenparallelität.

Isolationsstufe

Wie sich die Datenbank unter der Standardisolationsebene verhält, finden Sie unter https://www.jb51.net/article/116477.htm. Hier diskutieren wir nur die Konzepte von gemeinsamen Sperren und exklusiven Sperren, Lesen plus gemeinsame Sperren, Schreiben plus exklusive Sperren:

Auf der RC-Isolationsebene wird beim Ändern von Daten eine exklusive Sperre hinzugefügt. Die Sperre wird freigegeben, wenn die Transaktion endet, und andere Transaktionen dürfen die Sperre nicht lesen, wodurch das Dirty-Read-Problem gelöst wird. (Das gemeinsame Schloss wird sofort freigegeben)
Auf der RR-Isolationsebene wird den Lesedaten eine gemeinsame Sperre hinzugefügt und nach Abschluss der Transaktion freigegeben. Andere Transaktionen dürfen die Daten nicht ändern, wodurch das Problem des nicht wiederholbaren Lesens gelöst wird. (Die Shared-Lock-Transaktion wird beendet und freigegeben)

Tatsächlich werden alle Vorgänge serialisiert. Und Mysql hat es optimiert. Wenn eine Transaktion liest, können andere Transaktionen nicht schreiben, und wenn eine Transaktion schreibt, können andere Transaktionen nicht lesen? Ich kann die Probleme „Dirty Read“ und „Nicht wiederholbares Lesen“ immer noch lösen, ohne dies zu tun. MVCC ist erschienen. (Dadurch wird das Problem auch immer komplizierter und die Unterschiede treten unter der RR-Isolationsebene auf. Es kommt vor, dass die Standardisolationsebene von MySQL RR ist.)

MVCC

MVCC steht für Multi-Version Concurrency Control und löst durch die Verwendung von zwei Versionsnummern das Problem der Datenisolation. („Erstellen“ hat eine Versionsnummer, „Löschen“ hat eine Versionsnummer und der Änderungsvorgang ist in „Löschen“ und „Erstellen“ unterteilt.) Jede Transaktion generiert eine Versionsnummer, wenn sie mit dem Hinzufügen, Löschen, Ändern und Abfragen jeder Tabelle beginnt. Jede Transaktion kann nur Daten mit einer „Erstellen“-Nummer abfragen, die kleiner als diese Versionsnummer ist, und einer „Löschen“-Nummer, die größer als diese Versionsnummer ist. Auf diese Weise können die Vorgänge Hinzufügen, Löschen und Prüfen gleichzeitig ausgeführt werden und nur die Änderungsvorgänge müssen in die Warteschlange gestellt werden. Auf diese Weise wird das Problem nicht wiederholbarer Lesevorgänge auch ohne gemeinsame Sperren gelöst, da die Versionsnummer der Daten nach der Änderung der Daten durch andere Transaktionen größer als meine ist und ich sie nicht lesen werde.

MVCC-Parallelität auf RR-Isolationsebene

Nach der Einführung von MVCC scheint alles gut zu laufen. Haben Sie jedoch schon einmal darüber nachgedacht, was zwei Transaktionen lesen, wenn sie nacheinander ein Datenelement aktualisieren und diese Daten dann erneut lesen? Haha, das kann nicht passieren, da der Änderungsvorgang seriell ist und eine andere Transaktion diese Transaktion festschreiben muss, bevor sie geändert werden kann. OK, ändern wir die Frage. Zwei Transaktionen führen nacheinander eine +1-Operation an einem Datenelement aus. Nachdem die andere Transaktion festgeschrieben wurde, führt diese Transaktion erneut +1 aus und liest dann die Daten erneut. Wird diese Transaktion das Ergebnis von +1 oder +2 lesen? Wenn +2 gelesen wird, wird dadurch nicht die Isolierung zerstört und die von anderen Transaktionen übermittelten Daten gelesen?

Dies ist jedoch tatsächlich der Fall. Es wurden andere Transaktionen übermittelt, und diese Transaktion hat auch die Daten geändert. Natürlich muss anschließend +2 gelesen werden. Obwohl es ursprünglich 0 war und diese Transaktion nur 1 hinzugefügt hat, wurde es nach dem Lesen 2, was etwas unangenehm ist. Da alle Vorgänge unter der Standard-RR-Isolationsstufe seriell sind, können andere Transaktionen diese Daten nicht ändern, nachdem diese Transaktion eine Datenzeile gelesen hat. Diese Daten werden immer nur von dieser Transaktion bearbeitet, sodass die Isolation strikt eingehalten wird. MySQLs RR verbessert jedoch die Parallelität beim Lesen und Schreiben. Nur wenn zwei Transaktionen gleichzeitig ein Datenelement ändern, müssen sie serialisiert werden. Alle anderen Vorgänge können parallel ausgeführt werden. Dieses Ergebnis ist also darauf zurückzuführen, dass anscheinend ein nicht wiederholbarer Lesevorgang stattgefunden hat. Dieses nicht wiederholbare Lesen entspricht jedoch tatsächlich unserem intuitiven Gefühl. Nachdem die Daten in dieser Transaktion geändert wurden, müssen natürlich die neuesten Daten gelesen werden.

So analysieren Sie den Prozess:

Die Versionsnummer der Datenerstellung ist 0

Die Versionsnummer von Transaktion 1 ist 1, der Wert der gelesenen Daten ist 0.

Die Versionsnummer von Transaktion 2 ist 2, der geänderte Datenwert + 1 = 1, die Versionsnummer für das Löschen der ursprünglichen Daten ist 2, die Versionsnummer für das Erstellen neuer Daten wird auf 2 aktualisiert.

Transaktion 1 ändert den Datenwert + 1 = 2. (Da es sich bei der Änderung um den aktuellen Lesevorgang handelt, werden immer die Daten mit der höchsten Versionsnummer gelesen, sodass der gelesene Wert 1 ist.) Nach der Änderung ist die Löschversionsnummer 1.

Die neue Datenerstellungsversionsnummer ist 1

Diese Transaktion liest Datenwert=2

Detaillierte Analyse:

Tatsächlich weist die obige Beschreibung auch Lücken auf. Was ist, wenn es eine dritte Transaktion mit der Versionsnummer 3 gibt? Können wir die nicht festgeschriebenen Daten der Transaktionen 1 und 2 direkt lesen, da die Versionsnummer 3 ist? Tatsächlich hat in MVCC jede Transaktion auch eine minimal sichtbare Version low_limit_id (Datensätze mit Transaktionsnummer >= low_limit_id sind für die aktuelle Transaktion unsichtbar), die die Transaktionen herausfiltert, die aktuell ausgeführt, aber nicht festgeschrieben werden. Beispiel: Transaktion 3 hat zwar die Versionsnummer 3 und die low_limit_id ist 1, daher sind die von den Transaktionen 1 und 2 vorgenommenen Änderungen für Transaktion 3 nicht sichtbar.

Zusammenfassen

Um das Isolationsproblem zu lösen, wurde auf dumme Methoden wie das komplette Kopieren der Daten verzichtet. Herkömmliche Datenbanken verwenden gemeinsame Sperren und exklusive Sperren, um Lese- und Schreibvorgänge zu serialisieren. MySQL verwendet MVCC und exklusive Sperren, die die parallele Ausführung von Lese- und Schreibvorgängen ermöglichen. Mysql verhält sich auf Isolationsebenen unter RR genauso wie die traditionelle Methode. Auf Isolationsebene RR unterscheidet es sich von der traditionellen Methode. Dies spiegelt sich in der Tatsache wider, dass eine Transaktion, nachdem sie ein Datenelement aktualisiert hat, die von anderen Transaktionen an dem Datenelement vorgenommenen Änderungen lesen kann.

Das könnte Sie auch interessieren:
  • Zusammenfassung der Unterschiede zwischen den MySQL-Speicher-Engines MyISAM und InnoDB
  • Einstellen der Engine MyISAM/InnoDB beim Erstellen einer Datentabelle in MySQL
  • Umfassende Analyse von optimistischer Sperre, pessimistischer Sperre und MVCC in MySQL
  • Detaillierte Erläuterung der Speicherverwaltung der MySQL InnoDB-Speicher-Engine
  • Detaillierte Erläuterung verschiedener Sperren in der InnoDB-Speicher-Engine in MySQL
  • Detaillierte Erläuterung der Datenseitenstruktur der InnoDB-Speicher-Engine von MySQL
  • MySQL-Speicher-Engines InnoDB und MyISAM
  • Implementierungsprinzip der MVCC-Sperre der MySQL-Datenbank Innodb-Engine

<<:  Beispiel für die Installation von Kong Gateway in Docker

>>:  Detaillierte Erklärung, wie NGINX PV, UV und unabhängige IP der Website zählt

Artikel empfehlen

Node-Skript realisiert automatische Anmelde- und Lotteriefunktion

Inhaltsverzeichnis 1. Einleitung 2. Vorbereitung ...

Lösen Sie das Problem inkonsistenter Front- und Back-End-Ports von Vue

Die Front- und Back-End-Ports von Vue sind inkons...

Erfahren Sie mehr über die am häufigsten verwendeten JavaScript-Ereignisse

Inhaltsverzeichnis JavaScript-Ereignisse: Häufig ...

Frage zu benutzerdefinierten Attributen von HTML-Tags

In der vorherigen Entwicklung haben wir die Stand...

Deinstallieren der MySQL-Datenbank unter Linux

Wie deinstalliere ich eine MySQL-Datenbank unter ...

Strategie zur Optimierung der Leistung von MySQL-Datenbankabfragen

Optimieren von Abfragen Verwenden der Explain-Anw...

Führen Sie die Initialisierungs-SQL aus, wenn Docker MySQL startet

1. Ziehen Sie das Mysql-Image docker pull mysql:5...

Installieren Sie eine virtuelle Python-Umgebung in Ubuntu 18.04

Nur als Referenz für Python-Entwickler, die Ubunt...

Erläuterung der Array-Verarbeitung in React und Redux

Dieser Artikel stellt einige häufig verwendete Fu...