Ein kurzes Verständnis der relevanten Sperren in MySQL

Ein kurzes Verständnis der relevanten Sperren in MySQL

Dieser Artikel soll Ihnen vor allem dabei helfen, schnell das Wissen über Sperren in InnoDB zu verstehen.

Grundlegende Konzeptanalyse und detaillierte Quellcodeanalyse von RocketMQ

http://xiazai.jb51.net/202105/yuanma/RocketMQ_jb51.rar

Warum müssen wir sperren

Zunächst einmal: Warum sperren? Ich glaube, mehr muss ich dazu nicht sagen. Stellen Sie sich einfach die folgende Szene vor, dann verstehen Sie es.

Was tun Sie, wenn Sie in einem Einkaufszentrum auf die Toilette gehen? Schließ die Tür ab. Wenn Sie die Tür nicht abschließen und sie sich plötzlich öffnet, während Sie die Toilette benutzen, könnte das etwas unangemessen erscheinen.

Dasselbe gilt für Daten. In parallelen Szenarien wird die Konsistenz der Daten direkt zerstört, wenn die Daten nicht gesperrt sind. Wenn es bei Ihrem Geschäft um Geld geht, sind die Folgen noch schwerwiegender.

Sperren Sie das Tür-Ausdruckspaket

Sperrklassifizierung

Was sind die Sperren in InnoDB? Eigentlich solltest du schon viel wissen. Im Vorstellungsgespräch wirst du beispielsweise nach dem Unterschied zwischen den Speicher-Engines MyISAM und InnoDB gefragt. Du wirst sagen, dass MyISAM nur Tabellensperren hat, InnoDB aber sowohl Zeilensperren als auch Tabellensperren unterstützt. Möglicherweise werden Sie auch gefragt, was der Unterschied zwischen optimistischer und pessimistischer Sperre ist.

Es gibt viele Konzepte und Substantive für Schlösser. Wenn Sie kein umfassendes Weltbild über Schlösser haben, wird es für Sie schwierig sein, sie zu verstehen. Als Nächstes werden wir diese Schlösser klassifizieren.

Je nach Granularität des Schlosses

Je nach Granularität des Schlosses kann es in folgende Kategorien unterteilt werden:

  • Tabellensperre
  • Zeilensperre

Wir werden hier nicht auf Seitensperren eingehen, da es sich bei Seitensperren um ein Konzept handelt, das nur in der Speicher-Engine BDB (BerkeleyDB) existiert. Wir werden hier hauptsächlich die Speicher-Engine InnoDB besprechen.

Nach der Idee des Schlosses

Nach der Idee der Verriegelung kann sie unterteilt werden in:

  • Pessimistische Sperre
  • Optimistisches Sperren

Pessimismus und Optimismus haben hier die gleiche Bedeutung wie die Substantive, die Sie normalerweise verstehen. Beim optimistischen Sperren wird davon ausgegangen, dass es eine hohe Wahrscheinlichkeit gibt, dass keine Konflikte auftreten, und es wird nur gesperrt, wenn es nötig ist. Beim pessimistischen Sperren wird davon ausgegangen, dass eine hohe Konfliktwahrscheinlichkeit besteht. Daher wird der Sperrvorgang ausgeführt, unabhängig davon, ob er erforderlich ist.

Nach Kompatibilität

Je nach Kompatibilität können Schlösser unterteilt werden in:

  • Gemeinsam genutzte Sperren
  • Exklusives Schloss

Ressourcen mit gemeinsam genutzten Sperren können mit anderen geteilt werden. Wenn jedoch exklusive Sperren hinzugefügt werden, können andere keine Vorgänge ausführen, ohne die Sperre zu erhalten.

Nach der Umsetzung der Sperre

Die Implementierung hier sind die spezifischen Arten von Sperren in InnoDB, und zwar:

  • Absichtssperren
  • Datensatzsperren
  • Lückenschlösser
  • Next-Key-Schlösser
  • Absichtssperren einfügen
  • AUTO-INC-Schlösser

Auch wenn Schlösser entsprechend dieser Klassifizierung unterteilt werden, kann die große Zahl an Schlossnamen dennoch für Verwirrung sorgen. Welche Art von Sperre wird beispielsweise hinzugefügt, wenn ich SELECT ... FOR UPDATE ?

Wir sollten das Wesentliche durch das Phänomen erkennen. Was ist das Wesentliche? Entscheidend ist, welchem ​​Objekt das Schloss hinzugefügt wird. Dies lässt sich leicht beantworten:

  • Zur Tabelle hinzugefügt
  • Zur Zeile hinzugefügt

Und welcher Art sind die den Zeilen hinzugefügten Sperren? Das Wesentliche besteht darin, dem Index eine Sperre hinzuzufügen.

Absichtssperre

InnoDB unterstützt Sperren unterschiedlicher Granularität, darunter Zeilensperren und Tabellensperren. Beispielsweise hält der Befehl lock tables eine exklusive Sperre für die entsprechende Tabelle. Um Sperren unterschiedlicher Granularität praktischer zu machen, hat InnoDB Intention-Sperren entwickelt.

Eine Intention Lock ist eine Sperre auf Tabellenebene, die angibt, welcher Sperrtyp bei der nächsten Transaktion verwendet wird. Es gibt die folgenden zwei Typen:

  • Shared Intention Lock (IS) gibt an, dass die Transaktion beabsichtigt, den Datensätzen in der Tabelle eine gemeinsame Sperre hinzuzufügen.
  • Das exklusive Intention Lock (IX) ist ein exklusives Schloss

Beispielsweise fügt select ... for share eine gemeinsame Absichtssperre hinzu, während SELECT .. FOR UPDATE eine exklusive Absichtssperre hinzufügt. Die Regeln lauten wie folgt:

  • Wenn eine Transaktion eine gemeinsame Sperre für eine Zeile in einer Tabelle erhalten möchte, muss sie zuerst eine gemeinsame oder exklusive Absichtssperre für die Tabelle erhalten.
  • Wenn Sie ein exklusives Schloss erwerben möchten, müssen Sie zunächst ein exklusives Absichtsschloss erwerben.

Die folgende Abbildung zeigt den gegenseitigen Ausschluss und die Kompatibilität dieser Schlosskombinationen.

Gemäß der obigen Tabelle gilt: Wenn sie miteinander kompatibel sind, kann die entsprechende Transaktion die Sperre erwerben. Wenn sie jedoch inkompatibel sind, kann die Sperre erst erworben werden, wenn die inkompatible Sperre aufgehoben wird.

Wenn Sie dies sehen, haben Sie möglicherweise Fragen, da die Absichtssperre nichts außer LOCK TBALES blockiert. Welchen Nutzen habe ich dann davon?

Um das Beispiel noch weiter zu verwenden: Angenommen, Transaktion A erhält eine gemeinsame Sperre für die Zeile mit der ID = 100 in der Studententabelle und anschließend muss Transaktion B eine exklusive Sperre für die Studententabelle beantragen. Diese beiden Sperren stehen offensichtlich im Konflikt und gelten für dieselbe Zeile.

Woher muss InnoDB wissen, dass A diese Sperre erworben hat? Den gesamten B+-Baum durchlaufen? Nein, die Antwort ist eine Absichtssperre. Wenn Transaktion B eine exklusive Sperre für die Schreibtabelle beantragt, stellt InnoDB fest, dass Transaktion A bereits eine beabsichtigte gemeinsame Sperre für die Tabelle erhalten hat, was darauf hinweist, dass die Studententabelle Datensätze enthält, die bereits durch eine gemeinsame Sperre gesperrt sind. Es wird zu diesem Zeitpunkt blockiert.

Darüber hinaus blockieren Intention Locks keine anderen Operationen außer Operationen wie LOCK TABLES . Mit anderen Worten: Absichtssperren stehen nur mit Sperren auf Tabellenebene im Konflikt, nicht mit Sperren auf Zeilenebene. Denn der Hauptzweck der Absichtssperre besteht darin, anzuzeigen, dass jemand dabei ist, eine Zeile zu sperren oder dies gerade tut.

Genau wie wenn Sie in die Bibliothek gehen, um nach einem Buch zu suchen, müssen Sie nicht jedes Bücherregal einzeln durchsuchen. Sie können einfach zum Service-Schalter gehen und am Computer suchen, um herauszufinden, ob die Bibliothek das Buch hat.

Datensatzsperre

Dies ist eine Datensatzsperre, eine Art Zeilensperre. Das Sperrobjekt der Datensatzsperre ist der Index, der dieser Datenzeile entspricht. Wenn Ihnen der Index nicht klar ist, können Sie diesen Artikel lesen.

Wenn wir SELECT * FROM student WHERE id = 1 FOR UPDATE ausführen, wird dem Index eine Datensatzsperre mit dem Wert 1 hinzugefügt. Was passiert, wenn in einer Tabelle kein Index vorhanden ist? Dieses Problem wurde auch im oben genannten Artikel erklärt. Wenn für eine Tabelle kein Primärschlüssel definiert ist, erstellt InnoDB eine versteckte RowID und verwendet diese RowID, um einen gruppierten Index zu erstellen. Nachfolgende Datensatzsperren werden auch auf diesen versteckten gruppierten Index gesetzt.

Wenn wir eine Transaktion starten, um die Zeile mit der ID = 1 zu aktualisieren, und wir die Transaktion nicht sofort festschreiben und dann eine weitere Transaktion starten, um die Zeile mit der ID = 1 zu aktualisieren, wird uns die Meldung lock_mode X locks rec but not gap waiting , wenn wir show engine innodb status verwenden.

X steht für exklusive Sperre. Daraus können wir erkennen, dass Datensatzsperren tatsächlich in gemeinsame Sperren und exklusive Sperren unterteilt werden können. Wenn wir FOR UPDATE verwenden, ist es exklusiv, und wenn wir LOCK IN SHARE MODE verwenden, wird es geteilt.

gap , die im obigen Text erscheint, ist eine weitere Implementierung der Zeilensperre, die Lückensperre.

Lückensperre

Bei Gap Locks ist das gesperrte Objekt auch ein Index. Um die Lückensperre besser zu verstehen, sehen wir uns ein Beispiel an.

WÄHLEN SIE DEN NAMEN DES SCHÜLERS, DER ZWISCHEN 18 UND 25 JAHREN ALTER LIEGT, UM ZU AKTUALISIEREN

Angenommen, wir haben einen nicht gruppierten Index für age erstellt, verhindert die Ausführung dieser Anweisung, dass andere Transaktionen Daten mit dem Alter von 18–25 Jahren zur student hinzufügen, unabhängig davon, ob die Tabelle tatsächlich Daten mit dem Alter von 18–25 Jahren enthält. Dies liegt daran, dass das Wesentliche der Lückensperre darin besteht, einen Bereich im Index zu sperren und die Speicherung der Indizes im zugrunde liegenden B+-Baum in InnoDB geordnet ist.

Hier ist ein weiteres Beispiel:

SELECT * FROM student WHERE age = 10 FOR UPDATE;

Es ist erwähnenswert, dass das Alter hier kein eindeutiger Index, sondern ein einfacher nicht gruppierter Index ist. Zu diesem Zeitpunkt wird den Daten mit age = 10 eine Datensatzsperre hinzugefügt und die Lücke age < 10 wird gesperrt. Wenn die aktuelle Transaktion nicht festgeschrieben wird, werden andere Transaktionen blockiert, wenn sie Daten mit age < 10 einfügen möchten.

Gap-Locks sind eine Kompromisslösung für MySQL, die auf Leistungs- und Parallelitätsaspekten basiert und nur unter Repeatable Read (RR) verfügbar ist. Wenn die Isolationsebene der aktuellen Transaktion Read Committed (RC) ist, deaktiviert MySQL Gap-Locks.

Wie ich gerade sagte, werden Datensatzsperren in gemeinsam genutzte und exklusive Sperren unterteilt, und Lückensperren sind eigentlich dasselbe. Aber im Gegensatz zu Datensatzsperren schließen sich gemeinsame Lückensperren und exklusive Lückensperren nicht gegenseitig aus. Was ist hier los?

Wir müssen das Wesentliche noch durch das Phänomen erkennen. Was ist der Zweck der Lückensperre?

Um zu verhindern, dass andere Transaktionen Daten in die Lücke einfügen

Gemeinsam genutzte und exklusive Gap-Locks sind in diesem Ziel konsistent und können daher gleichzeitig existieren.

Pro-Tastensperre

Next-Key-Locks sind die letzte Art der Zeilensperrenimplementierung in InnoDB. Next-Key-Locks sind eigentlich eine Kombination aus Datensatzsperren und Lückensperren. Mit anderen Worten: Die angrenzende Schlüsselsperre fügt dem entsprechenden Index eine Datensatzsperre hinzu und sperrt zusätzlich ein Intervall.

Aber nicht alle temporären Schlüsselsperren funktionieren auf diese Weise. Für das folgende SQL:

Wählen Sie * aus dem Studenten, wobei ID = 23 ist.

In diesem Fall ist die id der Primärschlüssel und der eindeutige Index. Unabhängig davon, wie viele Daten von anderen Transaktionen eingefügt werden, gibt es immer nur ein Datenelement mit id = 23 . Das Hinzufügen einer Lückensperre ist derzeit völlig unnötig und verringert die Parallelität. Wenn der verwendete Index ein eindeutiger Index ist, wird die sofortige Schlüsselsperre daher auf eine Datensatzsperre herabgestuft.

Angenommen, wir haben drei Indexdatenelemente: 10, 20 und 30. Der mögliche Sperrbereich bei der temporären Tastensperre ist dann wie folgt:

  • (∞, 10]
  • (10, 20]
  • (20, 30]
  • (30, ∞)

Die standardmäßige Transaktionsisolationsebene von InnoDB ist Repeatable Read (RR). In diesem Fall verwendet InnoDB temporäre Schlüsselsperren, um Phantom-Lesevorgänge zu verhindern.

Um Phantom Read kurz zu erklären: Innerhalb einer Transaktion führen Sie zwei Abfragen aus. Die erste Abfrage gibt 5 Datenelemente zurück, die zweite Abfrage gibt jedoch 7 Datenelemente zurück. Dies ist ein Phantom Read.

Sie haben vielleicht in vielen früheren Blogs oder Interview-Essays erfahren, dass die RR-Transaktionsisolationsebene von InnoDB Phantom-Lesevorgänge verhindern kann. Der Schlüssel zur Verhinderung von Phantom-Lesevorgängen in RR ist die temporäre Schlüsselsperre.

Angenommen, die Studententabelle enthält zwei Zeilen mit den IDs 90 und 110.

Wählen Sie * aus dem Studenten, wobei ID > 100 für Update ist.

Nach der Ausführung dieser SQL-Anweisung fügt InnoDB Lückensperren zu den Intervallen (90, 110] und (110, ∞) hinzu und fügt eine Datensatzsperre zum Index mit der ID = 110 hinzu. Auf diese Weise können andere Transaktionen diesem Intervall keine neuen Daten hinzufügen, selbst wenn 100 überhaupt nicht existiert.

Absichtssperre einfügen

Als nächstes folgen die Insert Intention Locks, die hinzugefügt werden, bevor wir INSERT Anweisung ausführen. Im Wesentlichen eine Art Lückenschloss.

Nehmen wir noch einmal ein Beispiel. Angenommen, wir haben jetzt die Indexdatensätze 10 und 20. Die Transaktionen A und B fügen Daten mit den Indexwerten 14 bzw. 16 ein. Zu diesem Zeitpunkt verwenden die Transaktionen A und B die Einfügeabsichtssperre, um die Lücke zwischen 10 und 20 zu sperren. Nachdem sie die Einfügeabsichtssperre erhalten haben, erhalten sie exklusive Sperren für 14 und 16.

Zu diesem Zeitpunkt blockieren sich die Transaktionen A und B nicht gegenseitig, da sie unterschiedliche Zeilen einfügen.

Auto-Inkrement-Sperre

Schließlich gibt es noch AUTO-INC-Sperren. AUTO-INC-Sperren sind im Wesentlichen Tabellensperren, die etwas ganz Besonderes sind. Wenn Transaktion A Daten zu einer Tabelle hinzufügt, die AUTO_INCREMENT Spalte enthält, hält sie eine Auto-Inkrement-Sperre. Zu diesem Zeitpunkt müssen andere Transaktionen B warten, um sicherzustellen, dass Transaktion A eine kontinuierliche Selbstinkrementierung ohne Lücken in der Mitte erreicht.

Holen Sie sich die MQ-Lernmaterialien über den unten stehenden Link, einschließlich der Analyse grundlegender Konzepte und der detaillierten RocketMQ-Quellcodeanalyse. Sie werden ständig aktualisiert, verpassen Sie diese Lernmaterialien also nicht.

http://xiazai.jb51.net/202105/yuanma/RocketMQ_jb51.rar (Muss gesammelt werden)

Das Obige ist eine kurze Einführung in die Details der relevanten Sperren in MySQL. Weitere Informationen zu MySQL-Sperren finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • MySQL-Implementierung für pessimistisches und optimistisches Sperren
  • Die umfassendste Erklärung des Sperrmechanismus in MySQL
  • Tiefgreifendes Verständnis der verschiedenen Sperren von MySQL

<<:  Der Typ der Schaltfläche ist nicht als „Senden“ angegeben. Durch Klicken auf die Schaltfläche wird nicht zur angegebenen URL gesprungen.

>>:  Beispiele für minimalistisches Website-Design

Artikel empfehlen

Ausführliche Erklärung verschiedener binärer Objektbeziehungen in JavaScript

Inhaltsverzeichnis Vorwort Beziehungen zwischen v...

JavaScript zur Implementierung der Webversion des Schlangenspiels

In diesem Artikel wird der spezifische Code für J...

Einführung und Beispiele für versteckte Felder in HTML

Grundlegende Syntax: <Eingabetyp="versteck...

MySQL 8.0.21-Installationstutorial unter Windows-System (Abbildung und Text)

Installationsvorschlag : Versuchen Sie, für die I...

js realisiert das Verpacken mehrerer Bilder in Zip

Inhaltsverzeichnis 1. Dateien importieren 2. HTML...

Einführung in Sublime Text 2, ein Web-Frontend-Tool

Sublime Text 2 ist ein leichter, einfacher, effiz...

So verwenden Sie Webpack und Rollup zum Verpacken von Komponentenbibliotheken

Vorwort Ich habe zuvor eine Komponente im Ladesti...

Zählen Sie die Listen-Tags in HTML

1. <dl> definiert eine Liste, <dt> de...