https://dev.mysql.com/doc /refman/5.6/en/innodb-lock-modes.html dice:
Ciò significa che più thread possono acquisire blocchi IX. Questi blocchi sono a livello di tabella, non a livello di riga. Un blocco IX significa che il thread che lo contiene intende aggiornare alcune righe da qualche parte sul tavolo. I blocchi IX hanno solo lo scopo di bloccare le operazioni su tabelle complete.
Potrebbe far luce se consideri che funziona in entrambi i modi:se è in corso un'operazione su un'intera tabella, quel thread ha un blocco a livello di tabella che blocca un blocco IX.
Le operazioni DML devono prima acquisire un blocco IX prima di poter tentare blocchi a livello di riga. Il motivo è che non vuoi che DML sia consentito durante un ALTER TABLE
è in corso, o mentre qualche altro thread ha fatto LOCK TABLES...WRITE
.
Modifiche a livello di riga come UPDATE
, DELETE
, SELECT..FOR UPDATE
non sono bloccati da un blocco IX. Sono bloccati da altre modifiche a livello di riga o da un effettivo blocco completo della tabella (LOCK TABLES
o alcune istruzioni DDL). Ma a parte queste operazioni sulle tabelle, più thread che eseguono DML possono probabilmente funzionare contemporaneamente, purché ciascuno lavori su un insieme di righe che non si sovrappongono.
Re il tuo commento:
Il secondo SELECT...FOR UPDATE
non è bloccato in attesa del blocco IX, è bloccato in attesa dei blocchi X (a livello di riga) su righe che sono già bloccate da X-lock in un altro thread.
Ho appena provato questo e poi ho eseguito SHOW ENGINE INNODB STATUS
così ho potuto vedere la transazione bloccata:
---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
Vedere? Dice che è in attesa di ottenere il blocco con lock_mode X sull'indice della chiave primaria della tabella test
. Questo è un blocco a livello di riga.
Re la tua confusione su LOCK IN SHARE MODE
:
Stai parlando di tre livelli di SELECT
.
SELECT
non richiede serrature. Nessun blocco lo blocca e non blocca altri blocchi.SELECT ... LOCK IN SHARE MODE
richiede un blocco IS sulla tabella, quindi S blocca le righe che corrispondono alla scansione dell'indice. Più thread possono contenere blocchi IS o blocchi IX su una tabella. Più thread possono contenere lucchetti S contemporaneamente.SELECT ... FOR UPDATE
richiede un blocco IX sulla tabella, quindi X blocca le righe che corrispondono alla scansione dell'indice. I blocchi X sono esclusivi il che significa che non possono avere nessun altro thread per avere un blocco X o un lucchetto S sulla stessa riga.
Ma né i blocchi X né S si preoccupano dei blocchi IX o IS.
Pensa a questa analogia:immagina un museo.
Molte persone, sia visitatori che curatori, entrano nel museo. I visitatori vogliono vedere i dipinti, quindi indossano un badge etichettato "IS". I curatori possono sostituire i dipinti, quindi indossano un badge etichettato "IX". Possono esserci molte persone nel museo contemporaneamente, con entrambi i tipi di badge. Non si bloccano a vicenda.
Durante la loro visita, i seri fan dell'arte si avvicineranno il più possibile al dipinto e lo studieranno per lunghi periodi. Sono felici di lasciare che altri fan dell'arte stiano accanto a loro davanti allo stesso dipinto. Quindi stanno facendo SELECT ... LOCK IN SHARE MODE
e hanno i lucchetti a "S" perché almeno non vogliono che il dipinto venga sostituito mentre lo stanno studiando.
I curatori possono sostituire un dipinto, ma sono cortesi con gli appassionati d'arte seri e aspetteranno che questi spettatori abbiano finito e andranno avanti. Quindi stanno cercando di fare SELECT ... FOR UPDATE
(oppure semplicemente UPDATE
o DELETE
). In questo momento acquisiranno i blocchi "X", appendendo un piccolo cartello che dice "mostra in fase di ridisegno". I seri fan dell'arte vogliono vedere l'arte presentata in modo corretto, con una bella illuminazione e qualche placque descrittivo. Aspetteranno che la riprogettazione sia completata prima di avvicinarsi (ottengono un'attesa di blocco se ci provano).
Inoltre, probabilmente sei stato in un museo in cui i visitatori più casuali vagano, cercando di stare alla larga dalle altre persone. Guardano i dipinti dal centro della stanza, senza avvicinarsi troppo. Possono guardare gli stessi dipinti che altri spettatori stanno guardando e possono sbirciare oltre le spalle dei seri fan dell'arte, per guardare anche quei dipinti che vengono visualizzati. Potrebbero persino fissare i curatori mentre stanno sostituendo i dipinti (non importa se intravedono un dipinto che non è stato ancora montato e illuminato correttamente). Quindi questi visitatori occasionali non bloccano nessuno e nessuno blocca la loro visualizzazione. Stanno solo facendo SELECT
e non richiedono nessun lucchetto.
Ma ci sono anche operai edili che dovrebbero abbattere muri e cose del genere, ma non lavoreranno finché non c'è nessuno nell'edificio. Aspetteranno che tutti se ne vadano e, una volta iniziato il loro lavoro, non faranno entrare nessuno. È così che la presenza dei badge IS e IX blocca il DDL (i lavori di costruzione) e viceversa.