Caso de conflito oito

Fonte: conta pública yangyidba

I. Introdução

Deadlock é na verdade um problema técnico muito interessante e desafiador.Provavelmente, todo DBA e alguns desenvolvedores o encontrarão no processo de trabalho. Com relação ao impasse, continuarei a escrever uma série de estudos de caso, na esperança de ajudar amigos que desejam entender o impasse.

Análise de dois casos

2.1 Cenário de negócios

A principal lógica de negócios:

Primeiro execute os dados de inserção, se a inserção for bem-sucedida, então envie. Se um conflito de chave exclusiva for relatado ao inserir, a atualização será executada. Se três ações simultâneas de inicialização de dados ocorrerem ao mesmo tempo, as inserções de sess1 com sucesso, as inserções de sess2 e sess3 encontram um conflito de chave única e a inserção falha, ambas executarão a atualização, então o deadlock ocorre.

2.2 Preparação Ambiental

O nível de isolamento de transação do MySQL 5.6.24 é RR

create table ty (
  id int not null primary key auto_increment ,
  c1 int not null default 0,
  c2 int not null default 0,
  c3 int not null default 0,
  unique key uc1(c1),
  unique key uc2(c2)
) engine=innodb ;

insert into ty(c1,c2,c3) values(1,3,4),(6,6,10),(9,9,14);

2.3 Caso de teste

Para facilitar a análise do log de deadlock, os valores de c3 inseridos nas três sessões são 1 2 3 respectivamente, que na verdade são o mesmo valor em produção.


sess1

sess2

sess3


início;

início;

início;

T1

inserir em ty (c1, c2, c3) os valores (4,4,1);



T2


inserir em ty (c1, c2, c3) os valores (4,4,2);


T3



inserir em ty (c1, c2, c3) valores (4,4,3);

T4

comprometer



T5


atualizar ty set c3 = 5 onde c1 = 4;


T6



atualizar ty set c3 = 5 onde c1 = 4;

ERROR 1213 (40001): Deadlock encontrado ao tentar obter o bloqueio; tente reiniciar a transação

2.4 Registro de deadlock

2018-03-28 10:04:52 0x7f75bf2d9700
*** (1) TRANSACTION:
TRANSACTION 1870, ACTIVE 76 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 399265, OS thread handle 12, query id 9 root updating
update ty set c3=5 where c1=4
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 4 n bits 72 index uc1 of table 
`test`.`ty` trx id 1870 lock_mode X locks rec but not gap waiting
*** (2) TRANSACTION:
TRANSACTION 1871, ACTIVE 32 sec starting index read, 
thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 399937, OS thread handle 16, query id 3 root updating
update ty set c3=5 where c1=4
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 28 page no 4 n bits 72 index uc1 of table 
`test`.`ty` trx id 1871 lock mode S
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 4 n bits 72 index uc1 of table 
`test`.`ty` trx id 1871 lock_mode X locks rec but not gap waiting
*** WE ROLL BACK TRANSACTION (2)

Na verdade, basta olhar o log para ver que as atualizações das duas transações competem entre si, na ausência de cenários de lógica de negócios, porque não há operação de inserção, é difícil ter uma ideia eficaz para analisar o impasse.

2.5 Analise o log de deadlock

T1 s1 executa a operação de inserção, verifica a exclusividade e insere com êxito e mantém o bloqueio de linha da linha de registro c1 = 4.

A inserção T2 s2 encontra um conflito de chave exclusivo, solicite o bloqueio de bloqueio S O registro de bloqueio da próxima chave mostra o índice uc1 da tabela test.ty trx id 1870 modo de bloqueio S esperando

T3 é o mesmo que s2, a inserção s3 encontra um conflito de chave exclusivo, aplique o bloqueio de bloqueio S O registro de bloqueio da próxima chave mostra o índice uc1 da tabela test.ty trx id 1870 modo de bloqueio S esperando

T4 sess1 executa a operação de confirmação, neste momento sess2 e sess3 adquirem Lock S Next-key Lock ao mesmo tempo.

O aplicativo T5 recebe um conflito de chave exclusivo. A operação de atualização de sess2 precisa ser aplicada para um bloqueio de linha de c = 4, que é incompatível com o bloqueio de próxima chave Lock S mantido por sess3. Aguarde até que sess3 libere o bloqueio de chave próxima S de bloqueio.

T6 é semelhante ao sess2. A operação de atualização do sess3 precisa ser aplicada para um bloqueio de linha de c = 4, que é incompatível com o bloqueio da próxima chave Lock S mantido pelo sess2. Esperando que o sess2 libere o bloqueio da próxima chave Lock S. Uma espera cíclica ocorre e um deadlock ocorre.

2.6 Solução

A solução neste caso e de fato um impasse anterior em sete casos iguais, usando inserir na chave duplicada. O caso 7 é muito semelhante à lógica de negócios que causou o impasse neste artigo. Porque foi escrito pelo mesmo grupo de desenvolvedores.

Três resumos

A causa raiz do impasse é que a ordem de aplicação de bloqueios para transações diferentes é diferente e há espera cíclica. Ao projetar cenários de negócios de alta simultaneidade , os desenvolvedores precisam se concentrar neste ponto e tentar evitar impasses causados ​​por cenários de negócios não razoáveis.

Além disso, o mecanismo de travamento da inserção é na verdade mais complicado do que a atualização, o que requer mais prática para esclarecer o processo de travamento.

Digitalize o código QR para seguir a conta pública do autor no WeChat

Leitura estendida

O texto completo acabou.

Aproveite o MySQL :)

A aula "MySQL Core Optimization" do professor Ye foi atualizada para o MySQL 8.0, leia o código para iniciar a jornada de prática do MySQL 8.0

Acho que você gosta

Origin blog.csdn.net/n88Lpo/article/details/109233495
Recomendado
Clasificación