Detaillierte Erklärung, wie MySQL Phantom-Lesevorgänge löst

Detaillierte Erklärung, wie MySQL Phantom-Lesevorgänge löst

1. Was ist Phantomlesen?

Wenn bei einer Transaktion nach mehreren Abfragen die Anzahl der Ergebnissätze inkonsistent ist, nennt man das Phantomlesen.

Die zusätzliche oder fehlende Zeile wird als Phantomzeile bezeichnet.

2. Warum sollten wir das Phantomlesen lösen?

In einem Datenbanksystem mit hoher Parallelität muss die Isolation zwischen Transaktionen und die Konsistenz der Transaktionen selbst sichergestellt werden.

3. Wie löst MySQL das Phantomlesen?

Wenn Sie diesen Artikel lesen, gehe ich davon aus, dass Sie sich mit Dirty Reads, nicht wiederholbaren Reads und wiederholbaren Reads auskennen.

1. Multi-Version Concurrency Control (MVCC) (Snapshot-Lesen)

Die meisten Datenbanken implementieren eine Mehrversionen-Parallelitätskontrolle und alle sind dazu auf die Speicherung von Daten-Snapshots angewiesen.

Am Beispiel von InnoDB werden jeder Zeile zwei redundante Bytes hinzugefügt. Eine ist die erstellte Version der Zeile und eine ist die gelöschte (abgelaufene) Version der Zeile. Die Versionsnummer erhöht sich mit jeder Transaktion. Bei jedem Datenabruf durch eine Transaktion werden Daten abgerufen, deren Erstellungsversion kleiner als die aktuelle Transaktionsversion ist, und Daten, deren abgelaufene Version größer als die aktuelle Version ist.

Bei der normalen Auswahl handelt es sich um das Lesen eines Snapshots.

Wählen Sie * aus T, wobei Zahl = 1 ist;

Prinzip: Es wird ein Snapshot der historischen Daten gespeichert, sodass von anderen Transaktionen hinzugefügte oder gelöschte Daten für die aktuelle Transaktion nicht sichtbar sind.

2. Nächste-Tastensperre (aktueller Lesevorgang)

Das Nebenschlüsselschloss besteht aus zwei Teilen.

  1. Datensatzsperre (Zeilensperre)
  2. Lückensperre

Datensatzsperren sind Sperren, die zu Indizes hinzugefügt werden, und Lückensperren sind Sperren, die zwischen Indizes hinzugefügt werden. (Überlegen Sie: Was passiert, wenn für die Spalte kein Index vorhanden ist?)

Wählen Sie * aus T, wobei Zahl = 1 für Aktualisierung ist;
Wählen Sie * aus T, wobei Zahl = 1, Sperre im Freigabemodus;
einfügen
aktualisieren
löschen

Prinzip: Sperren Sie die Lücke zwischen der aktuellen Datenzeile und der vorherigen und nächsten Datenzeile, um sicherzustellen, dass die in diesem Bereich gelesenen Daten konsistent sind.

Sonstiges: Löst die RR-Isolationsebene der MySQL InnoDB-Engine das Phantom-Leseproblem? Verweisen Sie auf eine Kommentaradresse auf GitHub:

Die offizielle Erklärung von MySQL zum Phantomlesen lautet: Solange in der zweiten Auswahl einer Transaktion eine zusätzliche Zeile vorhanden ist, wird dies als Phantomlesen betrachtet.
Transaktion a wählt zuerst aus und Transaktion b fügt ein, was tatsächlich eine Lückensperre hinzufügt. Wenn Transaktion b jedoch festschreibt, wird die Lückensperre freigegeben (danach kann Transaktion a nach Belieben DML-Operationen ausführen). Das Ergebnis der Auswahl von Transaktion a ist dasselbe wie die erste Auswahl unter MVCC. Dann aktualisiert Transaktion a bedingungslos und diese Aktualisierung wirkt sich auf alle Zeilen aus (einschließlich der von Transaktion b neu hinzugefügten). Wenn Transaktion a erneut auswählt, wird die neue Zeile in Transaktion b angezeigt und diese neue Zeile wurde durch die Aktualisierung geändert. Dies ist tatsächlich auf der RR-Ebene der Fall.

Wenn dies der Fall ist, kann die RR-Ebene von MySQL Phantom-Lesevorgänge nicht verhindern.

Ein Freund antwortete an die Adresse:

Beim Lesen von Snapshots verwendet MySQL MVCC, um Phantomlesevorgänge zu vermeiden.
In der aktuellen Lese-Lese-Situation verwendet MySQL Next-Key, um Phantomlesevorgänge zu vermeiden.
select * from t where a=1; gehört zum Snapshot-Lesen
select * from t where a=1 lock im Share-Modus; gehört zum aktuellen Lesezugriff

Wenn die Ergebnisse des Snapshot-Lesevorgangs und des aktuellen Lesevorgangs unterschiedlich sind, kann dies nicht als Phantom-Lesevorgang betrachtet werden. Dies sind zwei verschiedene Verwendungszwecke. Daher denke ich, dass die RR-Ebene von MySQL das Problem des Phantomlesens löst.

Lassen Sie mich zunächst das Fazit ziehen. Die Isolationsebene RR der MySQL-Speicher-Engine InnoDB löst das Phantom-Lese-Problem.

Wie in der vorherigen Frage erwähnt, werden die in T2 eingefügten Daten zusammen aktualisiert, wenn T1 nach der Auswahl aktualisiert wird. Es wird also davon ausgegangen, dass eine zusätzliche Zeile vorhanden ist, sodass ein Phantomlesen nicht verhindert werden kann. Diese Aussage scheint einwandfrei, ist aber tatsächlich falsch. InnoDB hat zwei Modi: Snapshot-Lesen und aktuelles Lesen. Wenn nur Snapshot-Lesen möglich ist, gibt es natürlich kein Phantom-Lesen-Problem. Wenn die Aussage jedoch zum aktuellen Lesen hochgestuft wird, muss T1 bei der Auswahl die folgende Syntax verwenden: select * from t for update (Sperre im Freigabemodus), um in das aktuelle Lesen zu wechseln, dann kann T2 natürlich keine Daten einfügen.

Beachten
Next-Key löst das Phantom-Read-Problem zwar sehr gut, es gilt aber dennoch die allgemeine Regel, dass die Parallelität umso geringer ist, je höher die Isolationsstufe ist.

Oben finden Sie eine ausführliche Erklärung, wie MySQL Phantom-Lesevorgänge löst. Ich hoffe, dass sie Ihnen hilfreich sein wird. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht und ich werde Ihnen rechtzeitig antworten. Ich möchte auch allen für ihre Unterstützung der Website 123WORDPRESS.COM danken!

Das könnte Sie auch interessieren:
  • Beispiel für die Verwendung von MySQL-Transaktionsfunktionen zur Implementierung einer gleichzeitigen und sicheren Auto-Increment-ID
  • Lösung für das Problem der gesperrten Transaktionsverarbeitung mit hoher Parallelität in PHP+MySQL
  • Kann die wiederholbare Leseebene von MySQL Phantomlesevorgänge lösen?
  • Lösung für das Problem der MySQL-Transaktionsparallelität
  • Detaillierte Erklärung zu MySQL-Phantomlesevorgängen und wie man sie eliminiert
  • MySQL Series 10 MySQL-Transaktionsisolierung zur Implementierung der Parallelitätskontrolle
  • So lösen Sie das Phantomleseproblem in MySQL
  • mysql + mybatis implementiert gespeicherte Prozedur + Transaktion + gleichzeitigen Mehrfachabruf von Seriennummern
  • Detaillierte Erläuterung des gleichzeitigen Dirty Read + nicht wiederholbaren Read + Phantom Read in MySQL-Transaktionen

<<:  Node implementiert Suchfeld für Fuzzy-Abfragen

>>:  Beispiel für die Verwendung von Javascript zum Ziehen und Tauschen von Div-Positionen

Artikel empfehlen

CSS: besuchte geheime Erinnerungen des Pseudoklassenselektors

Gestern wollte ich a:visited verwenden, um die Fa...

MySQL 5.6.27 Installations-Tutorial unter Linux

In diesem Artikel finden Sie das Installations-Tu...

Probleme bei der Installation von TensorRT im Docker-Container

Deinstallieren Sie die installierte Version auf U...

HTML-Tags: Sub-Tag und Sup-Tag

Heute stelle ich zwei HTML-Tags vor, die ich nich...

Tkinter verwendet JS-Canvas, um Farbverlaufsfarben zu erzielen

Inhaltsverzeichnis 1. Verwenden Sie RGB zur Darst...

Lösung für das Problem der langsamen Docker-Pull-Image-Geschwindigkeit

Derzeit verfügt Docker über einen offiziellen Mir...

So blockieren Sie IP und IP-Bereich in Nginx

Vorne geschrieben Nginx ist nicht nur ein Reverse...

Zusammenfassung der Wissenspunkte des Nodejs-Clustermoduls und Anwendungsbeispiele

Der Interviewer wird Sie manchmal fragen: „Sagen ...

VUE+Canvas realisiert den gesamten Prozess eines einfachen Gobang-Spiels

Vorwort In Bezug auf das Layout ist Gobang viel e...

MySQL 5.5.56 - Installationsfreie Versionskonfigurationsmethode

Die Konfigurationsmethode der kostenlosen Install...

Drei Möglichkeiten, das horizontale Div-Layout auf beiden Seiten auszurichten

In diesem Artikel werden hauptsächlich drei Metho...