Detaillierte Erklärung zu MySQL-Phantomlesevorgängen und wie man sie eliminiert

Detaillierte Erklärung zu MySQL-Phantomlesevorgängen und wie man sie eliminiert

Dies ist ein populärwissenschaftlicher Artikel über Datenbankisolationsebenen. Ziel ist es, das berühmte Phantom-Read-Phänomen in Datenbanken zu verstehen. Um sich auf das Thema zu konzentrieren, werden Dirty Reads und nicht wiederholbare Lesevorgänge nicht behandelt.

Transaktionsisolationsebene

MySQL verfügt über vier Transaktionsisolationsebenen:

Read-uncommitted: Es gibt Probleme mit Dirty Read, nicht wiederholbarem Read und Phantom Read. Read-committed: Es gibt keine Dirty Read-, aber Probleme mit nicht wiederholbarem Read und Phantom Read. Repeatable-read: Es gibt keine Dirty Read-, nicht wiederholbaren Read- und Phantom Read-Probleme, aber es gibt Probleme mit Phantom Read. Serialisierung: Es werden Probleme mit Dirty Read, nicht wiederholbarem Read und Phantom Read gelöst, aber die Ausführung ist vollständig seriell und die Leistung ist am niedrigsten.

Was ist Phantomlesen?

Falsches Verständnis von Phantomlesen: Phantomlesen bedeutet, dass Transaktion A zwei Auswahlvorgänge ausführt, um unterschiedliche Datensätze zu erhalten, d. h. Auswahl 1 erhält 10 Datensätze und Auswahl 2 erhält 11 Datensätze. Dabei handelt es sich eigentlich nicht um einen Phantomlesevorgang, sondern um eine Art nicht wiederholbaren Lesevorgang, der nur auf der RU-RC-Ebene, nicht jedoch auf der MySQL-Standard-RR-Isolationsebene auftritt.

Hier ist mein Verständnis von Phantomlesen:

Phantom-Lesevorgänge bedeuten nicht, dass die aus mehreren Lesevorgängen in einer Transaktion erhaltenen Ergebnismengen unterschiedlich sind. Wichtiger bei Phantom-Lesevorgängen ist, dass der durch die aus einer bestimmten Auswahloperation erhaltene Ergebnismenge dargestellte Datenzustand nachfolgende Geschäftsoperationen nicht unterstützen kann. Genauer gesagt: Der ausgewählte Datensatz existiert nicht und Sie möchten diesen Datensatz einfügen. Wenn Sie jedoch den Befehl Einfügen ausführen, stellen Sie fest, dass dieser Datensatz bereits vorhanden ist und nicht eingefügt werden kann, genau wie eine Illusion

Ein Beispiel mag das Verständnis erleichtern:

mysql> zeigen erstellen Tabelle user\G
*************************** 1. Reihe ***************************
 Tabelle: Benutzer
Tabelle erstellen: CREATE TABLE `user` (
 `id` int(11) NICHT NULL,
 `name` varchar(32) DEFAULT NULL,
 PRIMÄRSCHLÜSSEL (`id`)
) ENGINE=InnoDB STANDARD-CHARSET=utf8

Starten Sie zwei Transaktionen T1 und T2 und stellen Sie ihre Isolationsebenen auf Reaptable-Read ein:

T1:

mysql> globale Transaktionsisolationsebene für wiederholbares Lesen festlegen;      
​
mysql> beginnen;
mysql> wähle * vom Benutzer aus;
mysql> in Benutzerwerte einfügen (1, 'Jeff');
FEHLER 1062 (23000): Doppelter Eintrag „1“ für Schlüssel „PRIMARY“
​
mysql> wähle * vom Benutzer aus;

T2:

mysql> globale Transaktionsisolationsebene für wiederholbares Lesen festlegen;      
​
mysql> beginnen;
mysql> in Benutzerwerte einfügen (1, 'Jeff');
mysql> festschreiben;

Die T1-Transaktion prüft, ob in der Tabelle ein Datensatz mit der ID 1 vorhanden ist, und fügt ihn ein, wenn nicht.

T2 fügt Interferenzdatensätze ein, die Phantomlesevorgänge in T1 verursachen.

Im obigen Beispiel muss sichergestellt werden, dass die Ausführung der Transaktion T1 vor der Ausführung der Transaktion T2 beginnt.

Im obigen Beispiel tritt bei T1 ein Phantomlesen auf, da der von T1 gelesene Datenzustand einen semantischen Konflikt mit den nachfolgenden Aktionen aufweist: Bei der Abfrage wird eindeutig darauf hingewiesen, dass der Datensatz nicht vorhanden ist, beim Einfügen jedoch darauf hingewiesen, dass der Primärschlüssel wiederholt wird, was dem Auftreten eines Phantoms ähnelt und daher als Phantomlesen bezeichnet wird.

So vermeiden Sie Phantom-Reads

MySQL bietet derzeit zwei Möglichkeiten, Phantom-Lesevorgänge zu verhindern:

1. Fügen Sie der Auswahloperation manuell eine Zeile-X-Sperre hinzu (SELECT ... FOR UPDATE). Der Grund dafür ist, dass die Zeilensperre in InnoDB den Index sperrt. Selbst wenn der aktuelle Datensatz nicht existiert, erhält die aktuelle Transaktion eine Datensatzsperre (wenn der Datensatz existiert, wird eine Zeilen-X-Sperre hinzugefügt, wenn er nicht existiert, wird eine Lücken-X-Sperre für die nächste Schlüsselsperre hinzugefügt). Auf diese Weise können andere Transaktionen keine Datensätze dieses Index einfügen, wodurch Phantom-Lesevorgänge vermieden werden.
2. Erhöhen Sie den Isolationsgrad weiter auf SERIALIZABLE
Testen Sie die Wirkung

mysql> beginnen;
​
mysql> wähle * vom Benutzer, wobei ID = 2 für Update;
mysql> in Benutzerwerte einfügen (2, 'Tony');

mysql> festschreiben;

T2:

mysql> beginnen;
​
mysql> in Benutzerwerte einfügen (2, 'Jimmy');
FEHLER 1062 (23000): Doppelter Eintrag „2“ für Schlüssel „PRIMARY“

Wenn T1 nun mit „Update“ abgefragt wird, wird der Index in Innodb gesperrt (auch wenn er derzeit nicht existiert), sodass das Einfügen der Transaktion T2 blockiert wird, bis T1 festgeschrieben ist. Auf diese Weise ist T1 erfolgreich. Für T1 wird das Phantomlesen tatsächlich eliminiert, aber das Einfügen von T2 wird einen doppelten Primärschlüssel melden, was ebenfalls den Erwartungen entspricht.

Wer interessiert ist, kann eine andere Möglichkeit ausprobieren, die Isolationsstufe zu verbessern und Phantom-Lesevorgänge zu eliminieren. Ich werde es hier nicht wiederholen. Das Prinzip ist ähnlich, außer dass das System die manuelle Sperrung ersetzt.

Zusammenfassen

RR ist die Standardisolationsebene von MySQL-Transaktionen. Sie stellt einen Kompromiss zwischen Transaktionssicherheit und Leistung dar. Wenn Entwickler Phantom-Lesevorgänge richtig verstehen, können sie je nach Bedarf entscheiden, ob sie Phantom-Lesevorgänge verhindern möchten.

SERIALIZABLE ist pessimistisch und geht davon aus, dass Phantom-Lesevorgänge immer stattfinden werden. Daher fügt es automatisch und implizit exklusive Sperren für die von der Transaktion benötigten Ressourcen hinzu. Andere Transaktionen, die auf diese Ressource zugreifen, werden blockiert und warten. Die Transaktion ist sicher, aber die Leistung muss sorgfältig berücksichtigt werden.

InnoDB-Sperren dienen der Beachtung der Indizes. Sperren Sie den Zeilendatensatz. Wenn er vorhanden ist, fügen Sie eine X-Sperre hinzu. Andernfalls fügen Sie eine Next-Key-Sperre / Lückensperre / Lückensperre hinzu. Daher kann InnoDB die Vorbelegung eines bestimmten Datensatzes durch eine Transaktion realisieren. Solange die Transaktion noch vorhanden ist, können andere Transaktionen sie nicht belegen. Zu Sperren folgt später noch ein gesonderter Artikel.

Oben finden Sie eine ausführliche Erklärung zu MySQL-Phantomlesevorgängen und wie man sie beseitigt. Weitere Informationen zu MySQL-Phantomlesevorgängen und wie man sie beseitigt, finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

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?
  • Detaillierte Erklärung, wie MySQL Phantom-Lesevorgänge löst
  • Lösung für das Problem der MySQL-Transaktionsparallelität
  • 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

<<:  Detaillierte Erklärung des TARGET-Attributs des HTML-Hyperlink-Tags A

>>:  So legen Sie die Speichergröße von Docker Tomcat fest

Artikel empfehlen

MySQL 8.0.17 Installations- und einfaches Konfigurationstutorial unter macOS

Wenn Sie nicht verstehen, was ich geschrieben hab...

Optimieren Sie MySQL mit 3 einfachen Tricks

Ich erwarte nicht, ein erfahrener Datenbankadmini...

Informationen zur Verwendung des Iconfont-Vektorsymbols von Alibaba in Vue

Es gibt viele Importmethoden im Internet, und die...

Implementierungsprinzip der MySQL MyISAM-Standardspeicher-Engine

Standardmäßig generiert die MyISAM-Tabelle drei D...

JavaScript-Webformularfunktion Kommunikation voller praktischer Informationen

1. Einleitung Vorher haben wir über das Front-End...

JavaScript-Grundlagenreihe: Funktionen und Methoden

Inhaltsverzeichnis 1. Der Unterschied zwischen Fu...

Element Plus implementiert Affix

Inhaltsverzeichnis 1. Komponenteneinführung 2. Qu...

Zusammenfassung von über 50 Hilfsfunktionen in JavaScript

JavaScript kann viele tolle Dinge. Dieser Artikel...

Docker unter Linux installieren (sehr einfache Installationsmethode)

Ich hatte in letzter Zeit ziemlich viel Zeit. Ich...

So bereinigen Sie schnell Milliarden von Daten in einer MySQL-Datenbank

Heute habe ich eine Festplattenalarm-Ausnahme erh...

js implementiert Array-Abflachung

Inhaltsverzeichnis So reduzieren Sie ein Array 1....

Allgemeine Array-Operationen in JavaScript

Inhaltsverzeichnis 1. verketten() 2. beitreten() ...