Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Warum ist ein IX-Lock mit einem anderen IX-Lock in InnoDB kompatibel?

https://dev.mysql.com/doc /refman/5.6/en/innodb-lock-modes.html sagt:

Dies bedeutet, dass mehrere Threads IX-Sperren erwerben können. Diese Sperren befinden sich auf Tabellenebene, nicht auf Zeilenebene. Eine IX-Sperre bedeutet, dass der Thread, der sie hält, beabsichtigt, einige Zeilen irgendwo zu aktualisieren in der Tabelle. IX-Sperren sind nur dazu gedacht, vollständige Tabellenoperationen zu blockieren.

Es kann etwas Licht ins Dunkel bringen, wenn Sie bedenken, dass es in beide Richtungen geht – wenn eine vollständige Tabellenoperation im Gange ist, dann hat dieser Thread eine Sperre auf Tabellenebene, die eine IX-Sperre blockiert.

DML-Vorgänge müssen zuerst eine IX-Sperre erwerben, bevor sie Sperren auf Zeilenebene versuchen können. Der Grund ist, dass Sie nicht wollen, dass DML während eines ALTER TABLE zugelassen wird ausgeführt wird oder während ein anderer Thread LOCK TABLES...WRITE ausgeführt hat .

Änderungen auf Zeilenebene wie UPDATE , DELETE , SELECT..FOR UPDATE werden nicht durch eine IX-Sperre blockiert. Sie werden durch andere Änderungen auf Zeilenebene oder durch eine tatsächliche vollständige Tabellensperre (LOCK TABLES , oder bestimmte DDL-Anweisungen). Aber abgesehen von diesen Tabellenoperationen können wahrscheinlich mehrere Threads, die DML ausführen, gleichzeitig arbeiten, solange sie jeweils an einer Reihe von Zeilen arbeiten, die sich nicht überschneiden.

Zu Ihrem Kommentar:

Der zweite SELECT...FOR UPDATE wird nicht beim Warten auf die IX-Sperre blockiert, sondern beim Warten auf X-Sperren (auf Zeilenebene) auf Zeilen, die bereits durch X-Sperren in einem anderen Thread gesperrt sind.

Ich habe das gerade ausprobiert und dann SHOW ENGINE INNODB STATUS ausgeführt damit ich die blockierte Transaktion sehen konnte:

---TRANSACTION 71568, ACTIVE 12 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 10, OS thread handle 140168480220928, query id 288 localhost root statistics
select * from test where id=1 for update
------- TRX HAS BEEN WAITING 12 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 802 page no 3 n bits 72 index `PRIMARY` of table `test`.`test` 
trx id 71568 lock_mode X locks rec but not gap waiting

Sehen? Es sagt, dass es darauf wartet, dass die Sperre mit lock_mode X auf dem Primärschlüsselindex gewährt wird der Tabelle test . Das ist eine Sperre auf Zeilenebene.

Beheben Sie Ihre Verwirrung über den LOCK IN SHARE MODE :

Sie sprechen von drei Ebenen von SELECT .

  • SELECT fordert keine Sperren an. Keine Sperren blockieren es und es blockiert keine anderen Sperren.
  • SELECT ... LOCK IN SHARE MODE fordert eine IS-Sperre für die Tabelle an und dann S-Sperren für Zeilen, die mit dem Index-Scan übereinstimmen. Mehrere Threads können IS-Sperren oder IX-Sperren für eine Tabelle halten. Mehrere Threads können gleichzeitig S-Locks halten.
  • SELECT ... FOR UPDATE fordert eine IX-Sperre für die Tabelle an, und dann X-Sperren für Zeilen, die mit dem Index-Scan übereinstimmen. X-Locks sind exklusiv was bedeutet, dass kein anderer Thread eine X-Sperre oder haben kann ein S-Schloss in derselben Zeile.

Aber weder X- noch S-Sperren kümmern sich um IX- oder IS-Sperren.

Denken Sie an diese Analogie:Stellen Sie sich ein Museum vor.

Viele Menschen, sowohl Besucher als auch Kuratoren, betreten das Museum. Die Besucher wollen Bilder sehen, also tragen sie eine Plakette mit der Aufschrift „IS“. Die Kuratoren dürfen Gemälde ersetzen, tragen also ein Abzeichen mit der Aufschrift „IX“. Mit beiden Arten von Ausweisen können sich viele Personen gleichzeitig im Museum aufhalten. Sie blockieren sich nicht gegenseitig.

Bei ihrem Besuch kommen die ernsthaften Kunstinteressierten so nah wie möglich an das Gemälde heran und studieren es ausgiebig. Gerne lassen sie andere Kunstinteressierte neben sich vor demselben Gemälde stehen. Sie machen daher SELECT ... LOCK IN SHARE MODE und sie haben "S"-Schlösser, weil sie zumindest nicht wollen, dass das Gemälde ersetzt wird, während sie es studieren.

Die Kuratoren können ein Gemälde ersetzen, aber sie sind den ernsthaften Kunstfans gegenüber höflich und warten, bis diese Betrachter fertig sind, und ziehen weiter. Sie versuchen also, SELECT ... FOR UPDATE auszuführen (oder einfach UPDATE oder DELETE ). Sie werden zu diesem Zeitpunkt "X"-Schlösser erwerben, indem sie ein kleines Schild mit der Aufschrift "Ausstellung wird neu gestaltet" aufhängen. Die ernsthaften Kunstfans möchten die Kunst auf angemessene Weise präsentiert sehen, mit schöner Beleuchtung und einigen beschreibenden Plaques. Sie warten, bis die Neugestaltung abgeschlossen ist, bevor sie sich nähern (sie erhalten eine Wartesperre, wenn sie es versuchen).

Außerdem waren Sie wahrscheinlich schon in einem Museum, in dem eher zufällige Besucher herumlaufen und versuchen, anderen aus dem Weg zu gehen. Sie betrachten Gemälde aus der Mitte des Raumes und kommen ihnen nicht zu nahe. Sie können dieselben Gemälde betrachten, die andere Betrachter betrachten, und sie können den ernsthaften Kunstfans über die Schulter schauen, um auch die betrachteten Gemälde zu sehen. Sie können sogar die Kuratoren anstarren, während sie Gemälde ersetzen (es ist ihnen egal, ob sie einen Blick auf ein Gemälde werfen, das noch nicht richtig montiert und beleuchtet wurde). Diese gelegentlichen Besucher blockieren also niemanden, und niemand blockiert ihre Anzeige. Sie machen nur SELECT und sie fordern keine Sperren an.

Aber es gibt auch Bauarbeiter, die Wände und so einreißen sollen, aber nicht arbeiten, solange jemand im Gebäude ist. Sie warten, bis alle gegangen sind, und sobald sie mit der Arbeit beginnen, lassen sie niemanden mehr herein. So blockiert das Vorhandensein von IS- und IX-Ausweisen DDL (die Bauarbeiten) und umgekehrt.