https://dev.mysql.com/doc /refman/5.6/nl/innodb-lock-modes.html zegt:
Dit betekent dat meerdere threads IX-sloten kunnen verkrijgen. Deze vergrendelingen bevinden zich op tafelniveau, niet op rijniveau. Een IX-slot betekent dat de thread die het bevat, van plan is om sommige rijen ergens bij te werken in de tafel. IX-sloten zijn alleen bedoeld om volledige tafeloperaties te blokkeren.
Het kan enig licht werpen als je bedenkt dat het beide kanten op gaat -- als er een volledige tafelbewerking aan de gang is, dan heeft die thread een vergrendeling op tafelniveau die een IX-vergrendeling blokkeert.
DML-bewerkingen moeten eerst een IX-vergrendeling verkrijgen voordat ze vergrendelingen op rijniveau kunnen proberen. De reden is dat u niet wilt dat DML wordt toegestaan terwijl een ALTER TABLE
bezig is, of terwijl een andere thread heeft gedaan LOCK TABLES...WRITE
.
Wijzigingen op rijniveau zoals UPDATE
, DELETE
, SELECT..FOR UPDATE
worden niet geblokkeerd door een IX-slot. Ze worden geblokkeerd door andere wijzigingen op rijniveau of door een daadwerkelijke volledige tafelvergrendeling (LOCK TABLES
, of bepaalde DDL-instructies). Maar afgezien van die tabelbewerkingen, kunnen meerdere threads met DML waarschijnlijk gelijktijdig werken, zolang ze maar werken aan een reeks rijen die elkaar niet overlappen.
Over uw opmerking:
De tweede SELECT...FOR UPDATE
is niet geblokkeerd bij het wachten op de IX-vergrendeling, het is geblokkeerd bij het wachten op de X-vergrendelingen (rijniveau) op rijen die al zijn vergrendeld door X-vergrendelingen in een andere thread.
Ik heb dit net geprobeerd en toen heb ik SHOW ENGINE INNODB STATUS
uitgevoerd zodat ik de geblokkeerde transactie kon zien:
---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
Zien? Het zegt dat het wacht op het slot met lock_mode X op de primaire sleutelindex van de tabel test
. Dat is een vergrendeling op rijniveau.
Opnieuw uw verwarring over LOCK IN SHARE MODE
:
Je hebt het over drie niveaus van SELECT
.
SELECT
verzoekt geen sloten. Geen sloten blokkeren het, en het blokkeert geen andere sloten.SELECT ... LOCK IN SHARE MODE
verzoekt om een IS-vergrendeling op de tafel, en vervolgens vergrendelt S op rijen die overeenkomen met de indexscan. Meerdere threads kunnen IS-sloten of IX-sloten op een tafel houden. Meerdere threads kunnen tegelijkertijd S-locks bevatten.SELECT ... FOR UPDATE
vraagt om een IX-vergrendeling op de tafel en vervolgens vergrendelt X op rijen die overeenkomen met de indexscan. X-sloten zijn exclusief wat betekent dat ze geen andere thread kunnen hebben met een X-lock of een S-slot op dezelfde rij.
Maar X- of S-sloten geven niet om IX- of IS-sloten.
Denk aan deze analogie:stel je een museum voor.
Veel mensen, zowel bezoekers als conservatoren, komen het museum binnen. De bezoekers willen schilderijen zien, dus dragen ze een badge met het opschrift "IS". De curatoren mogen schilderijen vervangen, dus dragen ze een badge met het label "IX". Er kunnen veel mensen tegelijk in het museum zijn, met beide soorten badges. Ze blokkeren elkaar niet.
Tijdens hun bezoek zullen de serieuze kunstliefhebbers zo dicht mogelijk bij het schilderij komen en het langdurig bestuderen. Ze laten graag andere kunstliefhebbers naast zich staan voor hetzelfde schilderij. Ze doen daarom SELECT ... LOCK IN SHARE MODE
en ze hebben "S"-sloten omdat ze in ieder geval niet willen dat het schilderij wordt vervangen terwijl ze het bestuderen.
De curatoren kunnen een schilderij vervangen, maar ze zijn hoffelijk tegenover de serieuze kunstliefhebbers, en ze zullen wachten tot deze kijkers klaar zijn en verder gaan. Dus ze proberen SELECT ... FOR UPDATE
. te doen (of anders gewoon UPDATE
of DELETE
). Ze zullen op dit moment "X" -sloten krijgen door een klein bordje op te hangen met de tekst "tentoonstelling wordt opnieuw ontworpen". De serieuze kunstliefhebbers willen de kunst op een goede manier gepresenteerd zien, met mooie verlichting en wat beschrijvende plaquettes. Ze wachten tot het herontwerp is voltooid voordat ze naderen (ze krijgen een slotwacht als ze het proberen).
Ook ben je waarschijnlijk in een museum geweest waar meer toevallige bezoekers ronddwalen, in een poging om uit de buurt van andere mensen te blijven. Ze bekijken schilderijen vanuit het midden van de kamer en komen niet te dichtbij. Ze kunnen naar dezelfde schilderijen kijken waar andere kijkers naar kijken, en ze kunnen over de schouders van de serieuze kunstfans gluren, om te kijken naar die schilderijen die ook worden bekeken. Ze kunnen zelfs naar de curatoren staren terwijl ze schilderijen vervangen (het kan ze niet schelen of ze een glimp opvangen van een schilderij dat nog niet goed is gemonteerd en verlicht). Dus deze toevallige bezoekers blokkeren niemand, en niemand blokkeert hun weergave. Ze doen gewoon SELECT
en ze vragen niet om sloten.
Maar er zijn ook bouwvakkers die geacht worden muren en zo af te breken, maar die werken niet als er iemand in het gebouw is. Ze wachten tot iedereen weg is, en als ze eenmaal met hun werk zijn begonnen, laten ze niemand meer binnen. Zo blokkeert de aanwezigheid van IS- en IX-badges DDL (de bouwwerkzaamheden) en vice versa.