Mysql
 sql >> Database >  >> RDS >> Mysql

Perché un blocco IX è compatibile con un altro blocco IX in InnoDB?

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.