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

So sichern Sie die MySQL-Datenbank regelmäßig automatisch

Wir alle wissen, dass Daten unbezahlbar sind. Wen...

Beispiele für die Verwendung von HTML-Listen-Tags dl, ul, ol

Code kopieren Der Code lautet wie folgt: <!-- ...

Details zum Prototypmodus des Javascript-Entwurfsmusters

Inhaltsverzeichnis 1. Prototyp-Modus Beispiel 1 B...

Detaillierte Erklärung zur Verwendung des CSS-Zeigerereignisse-Attributs

Bei der Frontend-Entwicklung stehen wir in direkt...

Erläuterung der objektorientierten Klassenvererbung in JavaScript

1. Objektorientierte Klassenvererbung In den obig...

Installieren Sie Apache2.4+PHP7.0+MySQL5.7.16 auf macOS Sierra

Obwohl Mac-Systeme mit PHP und Apache ausgeliefer...

Implementierungsprinzip und Nutzungsanalyse des Apache Bench-Stresstest-Tools

1: Durchsatz (Anfragen pro Sekunde) Eine quantita...

Detailliertes Verständnis des Lebenszyklusvergleichs zwischen Vue2 und Vue3

Inhaltsverzeichnis Zyklusvergleich Verwendung Zus...

Vue implementiert die Bildfrequenzwiedergabe des Karussells

In diesem Artikelbeispiel wird der spezifische Co...

Zusammenfassung der Überwachung von Tastaturereignissen durch Vue

Wichtige Modifikatoren Wenn wir auf Tastaturereig...

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

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