Caso de interbloqueo ocho

Fuente: cuenta pública yangyidba

I. Introducción

El punto muerto es en realidad un problema técnico muy interesante y desafiante, probablemente todos los administradores de bases de datos y algunos desarrolladores lo encontrarán en el proceso de trabajo. Con respecto al punto muerto, continuaré escribiendo una serie de estudios de casos, con la esperanza de ayudar a los amigos que quieran entender el punto muerto.

Análisis de dos casos

2.1 Escenario empresarial

La principal lógica empresarial:

Primero ejecute la inserción de datos, si la inserción es exitosa, luego envíela. Si se informa un conflicto de clave única al insertar, se realiza la actualización. Si se producen tres acciones de inicialización de datos simultáneas al mismo tiempo, las inserciones sess1 correctamente, las inserciones sess2 y sess3 encuentran un conflicto de clave única y la inserción falla, ambos ejecutarán la actualización, por lo que se producirá un punto muerto.

2.2 Preparación ambiental

El nivel de aislamiento de transacciones de MySQL 5.6.24 es 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 prueba

Para facilitar el análisis del log de interbloqueo, los valores de c3 insertados en las tres sesiones son 1 2 3 respectivamente, que en realidad son el mismo valor en producción.


sess1

sess2

sess3


empezar;

empezar;

empezar;

T1

insertar en ty (c1, c2, c3) valores (4,4,1);



T2


insertar en ty (c1, c2, c3) valores (4,4,2);


T3



insertar en ty (c1, c2, c3) valores (4,4,3);

T4

cometer



T5


actualizar ty set c3 = 5 donde c1 = 4;


T6



actualizar ty set c3 = 5 donde c1 = 4;

ERROR 1213 (40001): Se ha encontrado un interbloqueo al intentar obtener el bloqueo; intente reiniciar la transacción

2.4 Registro de interbloqueo

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)

De hecho, con solo mirar el registro solo se ve que las actualizaciones de las dos transacciones compiten entre sí. En ausencia de escenarios de lógica empresarial, es difícil tener una idea efectiva para analizar el punto muerto porque no sabe que hay una operación de inserción.

2.5 Analizar el registro de interbloqueo

T1 s1 ejecuta la operación de inserción, verifica la unicidad y se inserta correctamente, y mantiene el bloqueo de fila de la fila de registro c1 = 4.

El inserto T2 s2 encuentra un conflicto de clave único, solicite el bloqueo Bloqueo S El registro de bloqueo de la siguiente tecla muestra el índice uc1 de la tabla test.ty trx id 1870 modo de bloqueo S en espera

T3 es lo mismo que s2, el inserto s3 encuentra un conflicto de clave único, solicite el bloqueo Bloqueo S El registro de bloqueo de la siguiente tecla muestra el índice uc1 de la tabla test.ty trx id 1870 modo de bloqueo S en espera

T4 sess1 ejecuta la operación de confirmación, en este momento sess2 y sess3 adquieren Lock S Next-key Lock al mismo tiempo.

La aplicación T5 recibe un conflicto de clave única. La operación de actualización de sess2 necesita solicitar un bloqueo de fila de c = 4, que es incompatible con el bloqueo de tecla siguiente Lock S mantenido por sess3. Espere a que sess3 libere el bloqueo de tecla siguiente Lock S.

T6 es similar a sess2.La operación de actualización de sess3 necesita solicitar un bloqueo de fila de c = 4, que es incompatible con el bloqueo de tecla siguiente Lock S mantenido por sess2.Esperando que sess2 libere el bloqueo de tecla siguiente Lock S. Se produce una espera cíclica y se produce un punto muerto.

2.6 Solución

La solución en este caso y, de hecho, el bloqueo anterior en siete casos es el mismo, utilizando insertar en clave duplicada. El caso 7 es muy similar a la lógica empresarial que provocó el punto muerto en este artículo. Porque fue escrito por el mismo grupo de desarrolladores.

Tres resumen

La causa principal del interbloqueo es que el orden de aplicación de bloqueos para diferentes transacciones es diferente y hay una espera cíclica. Al diseñar escenarios comerciales de alta concurrencia , los desarrolladores deben centrarse en este punto y tratar de evitar los interbloqueos causados ​​por escenarios comerciales irrazonables.

Además, el mecanismo de bloqueo del inserto es en realidad más complicado que la actualización, lo que requiere más práctica para aclarar el proceso de bloqueo.

Escanee el código QR para seguir la cuenta pública de WeChat del autor

Lectura extendida

El texto completo ha terminado.

Disfruta MySQL :)

La clase "MySQL Core Optimization" de Teacher Ye se ha actualizado a MySQL 8.0, escanee el código para comenzar el viaje de la práctica de MySQL 8.0

Supongo que te gusta

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