Wie InnoDB Transaktionsisolationsebenen geschickt implementiert

Wie InnoDB Transaktionsisolationsebenen geschickt implementiert

Vorwort

Im vorherigen Artikel „Detaillierte Erklärung des MySQL-Sperrmechanismus“ haben wir den Sperrmechanismus von InnoDB ausführlich erklärt. Der Sperrmechanismus wird verwendet, um die Genauigkeit der Daten in gleichzeitigen Situationen sicherzustellen. Um die Datengenauigkeit sicherzustellen, sind normalerweise Transaktionen erforderlich. Die MySQL-Speicher-Engine InnoDB implementiert die vier Isolationsebenen in den Isolationseigenschaften von Transaktionen geschickt durch den Sperrmechanismus.

Transaktions-ACID-Eigenschaften, wobei I für Isolation steht. Isolation bedeutet, dass bei gleichzeitigen Transaktionen mehrerer Benutzer, die auf dieselbe Datenbank zugreifen, die Transaktion eines Benutzers nicht durch die Transaktionen anderer Benutzer gestört werden darf und mehrere gleichzeitige Transaktionen voneinander isoliert sein müssen.

Wir alle kennen die Eigenschaften von Transaktionen. Konsistenz und Isolation in der Datenbank sind die Grundideen für die Implementierung von Transaktionen. Wenn das System eine große Anzahl gleichzeitiger Zugriffe aufweist, spielt das Verständnis und die geschickte Anwendung der eigenen Transaktionsisolierungsebene der Datenbank eine Schlüsselrolle beim Schreiben von robustem Code mit starken gleichzeitigen Verarbeitungsfunktionen.

1. Wie Transaktionen sich gegenseitig beeinflussen

Wie stört eine Transaktion andere Transaktionen? Beispielsweise gibt es folgende Tabelle:

Tabelle erstellen lock_example(id smallint(10),name varchar(20),Primärschlüssel-ID)engine=innodb;

Die Tabelle enthält folgende Daten:

1, Zhangsan
2, Lisa
3, Wangwu

Demo1:

Transaktion A wird zuerst ausgeführt und befindet sich in einem nicht festgeschriebenen Zustand:

in t-Werte einfügen (4, „zhaoliu“);

Auch die später ausgeführte Transaktion B wird nicht festgeschrieben:

wähle * aus t;

Wenn Transaktion B den Datensatz lesen kann (4, zhaoliu), bedeutet dies, dass Transaktion A Auswirkungen auf Transaktion B hat. Diese Auswirkung wird als "Dirty Read" bezeichnet, dh der Datensatz nicht festgeschriebener Transaktionsvorgänge wird gelesen.

Demo 2:

Transaktion A, zuerst ausführen:

wähle * aus t, wobei ID=1;

Der Ergebnissatz ist

1, Zhangsan

Transaktion B wird später ausgeführt und festgeschrieben:

aktualisiere t setze Name=xxx, wobei ID=1 ist;

begehen;

Transaktion A führt dieselbe Abfrage erneut aus:

wähle * aus t, wobei ID=1;

Der Ergebnisset ist:

1, xxx

Dieses Mal hat die festgeschriebene Transaktion B Auswirkungen auf die Transaktion A. Diese Auswirkung wird als „nicht wiederholbares Lesen“ bezeichnet, d. h., die gleiche Abfrage innerhalb einer Transaktion führt zu unterschiedlichen Ergebnissen.

Demo 3:

Transaktion A, zuerst ausführen:

wähle * aus t, wo ID > 3;

Der Ergebnisset ist:

NULL

Transaktion B wird später ausgeführt und festgeschrieben:

in t-Werte einfügen (4, zhaoliu);

begehen;

Transaktion A fragt zuerst nach einer ID>3 und das Ergebnis ist NULL, daher möchte sie einen Datensatz mit der ID 4 einfügen:

in t-Werte einfügen (4, xxoo);

Der Ergebnisset ist:

Fehler: doppelter Schlüssel!

Sie denken vielleicht: . . Willst du mich verarschen? Ich habe es geprüft und es war ein leerer Satz, wenn ID>3, aber als ich ID=4 eingefügt habe, wurde mir angezeigt, dass ein PK-Konflikt vorliegt? →_→

Dieses Mal wird die Auswirkung der festgeschriebenen Transaktion B auf Transaktion A als „Phantomlesen“ bezeichnet.

Wie oben erwähnt, können gleichzeitige Transaktionen bei anderen Transaktionen zu Dirty Reads, nicht wiederholbaren Reads und Phantom Reads führen. Welche Anstrengungen hat InnoDB unternommen, um die oben genannte Situation zu vermeiden?

2. Welche Transaktionsisolationsebenen implementiert InnoDB?

InnoDB implementiert vier verschiedene Transaktionsisolationsebenen:

  • Nicht festgeschrieben lesen
  • Lesen bestätigt (RC)
  • Wiederholbares Lesen (RR)
  • Serialisierbar

Die Isolationsstufe verschiedener Transaktionen ist eigentlich ein Kompromiss zwischen Konsistenz und Parallelität.

3. Wie implementiert man die vier Transaktionsisolationsebenen in InnoDB?

InnoDB verwendet verschiedene Sperrstrategien, um unterschiedliche Isolationsebenen zu implementieren.

a. Nicht festgeschriebene Daten lesen

Auf dieser Transaktionsisolationsebene führt die Select-Anweisung nicht zu einer Sperre und stellt keinen Snapshot-Lesevorgang dar.

SELECT-Anweisungen werden ohne Sperren ausgeführt.

Zu diesem Zeitpunkt werden möglicherweise inkonsistente Daten gelesen, was als „Dirty Read“ bezeichnet wird. Dies ist die Isolationsebene mit der höchsten Parallelität und der schlechtesten Konsistenz.

b. Lesen Sie festgeschrieben (RC)

  • Die normale Auswahl ist das Lesen eines Snapshots.
  • Gesperrte Select-, Update- und Delete-Anweisungen verwenden nur Datensatzsperren, außer wenn eine Überprüfung auf Fremdschlüsseleinschränkungen und Duplikatschlüssel ausgeführt wird.
  • Gap-Lock und Next-Key-Lock sind auf dieser Ebene ungültig.

Zu diesem Zeitpunkt kann die Einfügung anderer Transaktionen noch ausgeführt werden, was dazu führen kann, dass Phantomdatensätze gelesen werden. Diese Ebene wird am häufigsten verwendet. Und wenn es sich um eine nicht gesperrte Auswahl handelt, kann es zu einem nicht wiederholbaren Lesevorgang kommen.

Auf dieser Ebene werden Dirty Reads durch Snapshot-Reads verhindert. Da Snapshot-Lesevorgänge auf dieser Ebene immer den neuesten Zeilendaten-Snapshot lesen können, muss dieser natürlich durch eine festgeschriebene Transaktion geschrieben werden, sodass nicht wiederholbare Lesevorgänge auftreten können.

c. Wiederholbares Lesen (RR)

Dies ist die Standardisolationsebene von InnoDB unter RR:

  • Bei der normalen Auswahl wird ein Snapshot-Read verwendet, ein konsistenter, nicht sperrender Read, der auf der untersten Ebene mithilfe von MVCC implementiert wird.
  • Gesperrte Select- (Select ... im Freigabemodus / Select ... für Update), Update-, Delete-Anweisungen usw., ihre Sperren hängen davon ab, ob sie eine eindeutige Suchbedingung (in diesem Fall werden Datensatzsperren verwendet) oder eine Suchbedingung vom Bereichstyp (in diesem Fall werden Lückensperren oder benachbarte Schlüsselsperren verwendet) auf einem eindeutigen Index verwenden.
  • Wenn eine eindeutige Abfragebedingung auf einen eindeutigen Index angewendet wird, wird eine Datensatzsperre verwendet, anstatt die Intervalle zwischen Datensätzen zu blockieren. Das heißt, es werden keine Lückensperre und keine Next-Key-Sperre verwendet.
  • Bei Bereichsabfragebedingungen oder nicht eindeutigen Indizes werden Lückensperren und benachbarte Schlüsselsperren verwendet, um den Bereich zwischen Indexdatensätzen zu sperren und so das Einfügen von Datensätzen zwischen Bereichen zu verhindern. Dadurch wird die Generierung von Phantomzeilendatensätzen und nicht wiederholbaren Lesevorgängen vermieden.

Auf dieser Ebene

  • Vermeiden Sie Phantom-Lesevorgänge und nicht wiederholbare Lesevorgänge, indem Sie Snapshot-Lesevorgänge und Sperrintervalle verwenden.
  • Der Zeitpunkt, zu dem eine Transaktion einen Datensatz zum ersten Mal liest, ist T. Zukünftig werden Datensätze, die von Transaktionen geschrieben wurden, die nach T festgeschrieben wurden, nicht mehr gelesen, um sicherzustellen, dass bei aufeinanderfolgenden Lesevorgängen derselbe Ergebnissatz gelesen wird. Dadurch können nicht wiederholbare Lesevorgänge verhindert werden.
  • Unter RR wird das Phantom-Lese-Problem durch Gap Lock und Adjacent Key Lock gelöst.

Serialisierbar

Auf dieser Transaktionsisolationsebene werden alle Select-Anweisungen implizit in Select ... im Share-Modus umgewandelt, was bedeutet, dass standardmäßig eine gemeinsame Lesesperre (S-Sperre) gesetzt ist.

Wenn Transaktion A also zuerst die folgende SQL-Anweisung ausführt, versucht sie, die IS-Sperre der abgefragten Zeile zu erhalten (die mit anderen IS- und IX-Sperren kompatibel ist). Zu diesem Zeitpunkt können auch andere Transaktionen die IS-Sperre oder sogar die S-Sperre dieser Zeilen erhalten. Wenn Transaktion A jedoch als nächstes einige der Zeilen aktualisiert oder löscht, erhält sie die X-Sperre. Andere Transaktionen werden blockiert, selbst wenn sie normale Select-Anweisungen ausführen, weil sie versuchen, die IS-Sperre zu erhalten. Die IS-Sperre und die X-Sperre schließen sich jedoch gegenseitig aus. Dadurch werden Dirty Reads, nicht wiederholbare Reads und Phantom Reads vermieden, und alle Transaktionen können nur seriell ausgeführt werden.

wählen ... ;

Dies ist die konsistenteste, aber am wenigsten gleichzeitige Isolationsebene. In Szenarien mit hoher Parallelität werden die beiden oben genannten Isolationsstufen a und d selten verwendet.

4. Fazit

Gegenseitige Interferenzen zwischen gleichzeitigen Transaktionen können Probleme wie Dirty Reads, nicht wiederholbare Reads und Phantom Reads verursachen.

InnoDB implementiert vier Isolationsebenen im SQL92-Standard:

  • Lesen nicht festgeschrieben: Die Auswahl ist nicht gesperrt, was zu fehlerhaften Lesevorgängen führen kann.
  • Read Committed (RC): Gewöhnliches Lesen eines ausgewählten Snapshots, Sperren von Auswahl/Aktualisierung/Löschen verwendet eine Datensatzsperre, was zu einem nicht wiederholbaren Lesevorgang führen kann.
  • Wiederholbares Lesen (RR): Normales Lesen ausgewählter Snapshots, Sperren von Auswahl/Aktualisierung/Löschen. Je nach Abfragebedingungen werden Datensatzsperre, Lückensperre/sofortige Schlüsselsperre ausgewählt, um das Lesen von Phantomdatensätzen zu verhindern.
  • Serialisierung: „select“ wird im Share-Modus implizit in „select ...“ konvertiert, was sich gegenseitig mit „update“ und „delete“ ausschließt.

Die Standardisolationsstufe von InnoDB ist RR und die am häufigsten verwendete Isolationsstufe ist RC

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • Tutorial zur Beziehung zwischen Innodb-Transaktionsisolationsebene und Sperre in MySQL
  • Einführung in die Transaktionsisolationsebene von MySQL-Datenbanken (Transaction Isolation Level)
  • Detaillierte Erklärung und Vergleich der vier Transaktionsisolationsebenen in MySQL
  • Detaillierte Analyse der MySQL-Transaktionsisolierung und ihrer Auswirkungen auf die Leistung
  • Detaillierte Erläuterung der vier Transaktionsisolationsebenen in MySQL
  • Detaillierte Erläuterung der Transaktionsisolierungsebenen der MySQL-Datenbank
  • Analyse der vier Transaktionsisolationsstufen in MySQL anhand von Beispielen

<<:  So richten Sie das Terminal so ein, dass Anwendungen nach dem Start von Ubuntu ausgeführt werden

>>:  So gehen Sie mit Zeitzonenproblemen in Docker um

Artikel empfehlen

Implementierungscode zur Verwendung der MongoDB-Datenbank in Docker

Holen Sie sich das Mongo-Image sudo docker pull m...

Vorteile von MySQL-Abdeckungsindizes

Ein allgemeiner Vorschlag besteht darin, Indizes ...

MySQL 8.0.20 Installations- und Konfigurations-Tutorial unter Docker

Docker installiert MySQL Version 8.0.20 zu Ihrer ...

Reagieren Sie mit Beispielcode zur Implementierung des Anmeldeformulars

Als Vue-Benutzer ist es an der Zeit, React zu erw...

Apache Calcite-Code zur Dialektkonvertierung

Definition Calcite kann SQL vereinheitlichen, ind...

Einrichten eines Proxyservers mit nginx

Nginx kann seine Reverse-Proxy-Funktion zum Imple...