Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Por que um IX-lock é compatível com outro IX-lock no InnoDB?


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

Isso significa que vários threads podem adquirir bloqueios IX. Esses bloqueios estão no nível da tabela, não no nível da linha. Um bloqueio IX significa que o thread que o contém pretende atualizar algumas linhas em algum lugar na mesa. Os bloqueios IX destinam-se apenas a bloquear operações de tabela completa.

Isso pode esclarecer um pouco se você considerar que isso ocorre nos dois sentidos - se uma operação de tabela completa estiver em andamento, esse encadeamento possui um bloqueio em nível de tabela que bloqueia um bloqueio IX.

As operações DML devem primeiro adquirir um bloqueio IX antes que possam tentar bloqueios em nível de linha. A razão é que você não quer que o DML seja permitido enquanto um ALTER TABLE está em andamento, ou enquanto algum outro thread fez LOCK TABLES...WRITE .

Alterações em nível de linha como UPDATE , DELETE , SELECT..FOR UPDATE não são bloqueados por um bloqueio IX. Eles são bloqueados por outras alterações em nível de linha ou por um bloqueio real de tabela completa (LOCK TABLES , ou certas instruções DDL). Mas, além dessas operações de tabela, vários threads executando DML provavelmente podem funcionar simultaneamente, desde que cada um deles esteja trabalhando em um conjunto de linhas que não se sobreponham.

Re seu comentário:

O segundo SELECT...FOR UPDATE não está bloqueado aguardando o bloqueio IX, está bloqueado aguardando os bloqueios X (nível de linha) em linhas que já estão bloqueadas por bloqueios X em outro thread.

Acabei de tentar isso e executei SHOW ENGINE INNODB STATUS para que eu pudesse ver a transação bloqueada:
---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

Ver? Ele diz que está aguardando a concessão do bloqueio com lock_mode X no índice de chave primária da tabela test . Isso é um bloqueio em nível de linha.

Re sua confusão sobre LOCK IN SHARE MODE :

Você está falando de três níveis de SELECT .
  • SELECT solicita nenhum bloqueio. Nenhum bloqueio o bloqueia e não bloqueia outros bloqueios.
  • SELECT ... LOCK IN SHARE MODE solicita um bloqueio IS na tabela e, em seguida, S bloqueia nas linhas que correspondem à verificação do índice. Vários threads podem conter bloqueios IS ou bloqueios IX em uma tabela. Vários encadeamentos podem conter bloqueios S ao mesmo tempo.
  • SELECT ... FOR UPDATE solicita um bloqueio IX na tabela e, em seguida, bloqueia X nas linhas que correspondem à verificação do índice. Os bloqueios X são exclusivos o que significa que eles não podem nenhum outro segmento ter um bloqueio X ou um bloqueio S na mesma linha.

Mas nem os bloqueios X nem S se preocupam com os bloqueios IX ou IS.

Pense nesta analogia:imagine um museu.

Muitas pessoas, tanto visitantes quanto curadores, entram no museu. Os visitantes querem ver as pinturas, então eles usam um crachá rotulado "IS". Os curadores podem substituir as pinturas, por isso usam um crachá com a etiqueta "IX". Pode haver muitas pessoas no museu ao mesmo tempo, com os dois tipos de crachás. Eles não bloqueiam um ao outro.

Durante a visita, os fãs sérios da arte se aproximarão da pintura o máximo que puderem e a estudarão por longos períodos. Eles ficam felizes em deixar outros fãs de arte ficarem ao lado deles antes da mesma pintura. Portanto, eles estão fazendo SELECT ... LOCK IN SHARE MODE e eles têm fechaduras "S" porque pelo menos não querem que a pintura seja substituída enquanto a estudam.

Os curadores podem substituir uma pintura, mas são corteses com os fãs de arte sérios e esperam até que esses espectadores terminem e sigam em frente. Então eles estão tentando fazer SELECT ... FOR UPDATE (ou então simplesmente UPDATE ou DELETE ). Eles vão adquirir fechaduras "X" neste momento, pendurando uma pequena placa dizendo "exposição sendo redesenhada". Os fãs sérios de arte querem ver a arte apresentada de maneira adequada, com boa iluminação e alguma placa descritiva. Eles esperarão que o redesenho seja feito antes de se aproximarem (eles recebem uma espera de bloqueio se tentarem).

Além disso, você provavelmente já esteve em um museu onde os visitantes mais casuais vagam, tentando ficar fora do caminho de outras pessoas. Eles olham para as pinturas do meio da sala, não se aproximando muito. Eles podem olhar para as mesmas pinturas que outros espectadores estão olhando, e eles podem espiar por cima dos ombros dos fãs de arte sérios, para ver as pinturas que estão sendo vistas também. Eles podem até ficar boquiabertos com os curadores enquanto eles estão substituindo as pinturas (eles não se importam se vislumbrar uma pintura que ainda não foi montada e iluminada adequadamente). Portanto, esses visitantes casuais não bloqueiam ninguém e ninguém bloqueia sua visualização. Eles estão apenas fazendo SELECT e eles não solicitam nenhum bloqueio.

Mas também há trabalhadores da construção civil que deveriam derrubar paredes e outras coisas, mas não trabalharão enquanto houver alguém no prédio. Eles esperam que todos saiam e, uma vez iniciados o trabalho, não deixam ninguém entrar. É assim que a presença dos crachás IS e IX bloqueia o DDL (o trabalho de construção) e vice-versa.