Caso de interbloqueo 6

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 DBA y algunos estudiantes de desarrollo lo encontrarán en el curso del 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.

2. Análisis de casos

2.1 Descripción ambiental

El nivel de aislamiento de transacciones de MySQL 5.6.24 es RR

create table tx (
  id int not null primary key auto_increment ,
  c1 int not null default 0,
  c2 int not null default 0,
  key idx_c1(c1)
) engine=innodb ;
insert into tx values(24,3,4),(25,3,4),
(26,3,4),(30,5,8);

2.2 Caso de prueba

2.3 Registro de interbloqueo

----------------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-03-27 15:40:40 0x7f75cafce700
*** (1) TRANSACTION:
TRANSACTION 1850, ACTIVE 20 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 379040, OS thread handle 140143994337024, query id 1521958 localhost root updating
update tx set c2=8 where c1=5
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 27 page no 3 n bits 72 index PRIMARY of table `test`.`tx` trx id 1850 lock_mode X locks rec but not gap waiting
*** (2) TRANSACTION:
TRANSACTION 1849, ACTIVE 32 sec updating or deleting, thread declared inside InnoDB 4999
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 379016, OS thread handle 140143893473024, query id 1521976 localhost root updating
delete from tx where id=30
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 27 page no 3 n bits 72 index PRIMARY of table `test`.`tx` trx id 1849 lock_mode X locks rec but not gap
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 27 page no 5 n bits 72 index idx_c1 of table `test`.`tx` trx id 1849 lock_mode X locks rec but not gap waiting
*** WE ROLL BACK TRANSACTION (1)

2.4 Analizar el registro de interbloqueo

Lo primero que debe comprender es que solicitar un bloqueo en el mismo campo requiere hacer cola.

En segundo lugar, el índice idx_c1 de la tabla ty es un índice ordinario no único, lo explicamos según la secuencia temporal de ejecución de la transacción, que es más fácil de entender.

T1: sess2 realiza la operación de selección para actualización y mantiene el bloqueo de fila de clave principal con id de registro = 30: PRIMARIO de la tabla test.tx lock_mode X bloquea rec pero no gap

T2: La actualización de la instrucción sess1 actualiza c2 a través del índice normal idx_c1, primero obtiene el bloqueo X lock_mode X locks rec pero no el espacio de idx_c1 c1 = 5, y luego aplica para el bloqueo de fila correspondiente a la clave principal id = 30, pero sess2 ya contiene el bloqueo de fila de la clave principal , Entonces sess1 espera.

T3: sess2 elimina registros basados ​​en la identificación de la clave principal = 30 y debe solicitar el bloqueo de fila con id = 30 y el bloqueo de fila de índice con c1 = 5. Pero sess1 y manteniendo el bloqueo, por lo que el índice idx_c1 de la tabla test.tx trx id 1849 lock_mode X bloquea rec pero no espera de espacio

sess2 (eliminar) espera a sess1 (actualización), sess1 (actualización) espera a que sess2 (seleccionar para actualizar) esperar en un bucle, provocando un punto muerto.

La causa raíz del interbloqueo en el sistema RDBMS se puede resumir de la siguiente manera: una secuencia de bloqueo de transacciones diferente conduce a una espera cíclica, que conduce a un interbloqueo.

2.5 Solución

Modifique la actualización de sess1 para actualizar en función de la clave principal, es decir, actualice el conjunto tx c2 = x donde id = 30 , cambie el modo de bloqueo a bloqueo secuencial, solicite el bloqueo de la identificación de la clave principal y evite el bloqueo cruzado y la aplicación mutua para las tenencias de cada uno bloquear.

Tres, resumen

El punto muerto en el caso anterior se debe a que las diferentes sesiones compiten entre sí en el índice común idx_c1 y la clave principal, lo que conduce a un punto muerto debido a la espera circular. Cuando encuentre una alta simultaneidad actualizando la misma fila en el proceso de producción, puede considerar evitar la actualización a través de diferentes índices para evitar un punto muerto.

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/108806208
Recomendado
Clasificación