Caso de interbloqueo 7

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 Escenario empresarial

Los estudiantes de desarrollo empresarial quieren sincronizar datos. Su lógica es actualizar a través de la operación de actualización. Si el efecto_rows devuelto por el registro actualizado es 0, entonces se llama a la instrucción insert para inicializar la inserción . Si la inserción falla, la operación de actualización se vuelve a realizar y se produce un interbloqueo en el caso de operaciones simultáneas de varias sesiones.

2.2 Descripció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

2.4 Registro de interbloqueo

2018-03-27 17:59:23 0x7f75bf39d700
*** (1) TRANSACTION:
TRANSACTION 1863, ACTIVE 76 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 382150, OS thread handle 56640, query id 28 localhost root update
insert into ty (c1,c2,c3) values(3,4,2)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 5 n bits 72 index uc2 of table `test`.`ty` trx id 1863 lock_mode X locks gap before rec insert intention waiting
*** (2) TRANSACTION:
TRANSACTION 1864, ACTIVE 65 sec inserting, thread declared inside InnoDB 5000
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 382125, OS thread handle 40032, query id 62 localhost root update
insert into ty (c1,c2,c3) values(3,4,2)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 28 page no 5 n bits 72 index uc2 of table `test`.`ty` trx id 1864 lock_mode X locks gap before rec
*** (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 1864 lock mode S waiting
*** WE ROLL BACK TRANSACTION (2)

2.5 Analizar el registro de interbloqueo

En primer lugar, debemos volver a enfatizar la lógica de bloqueo de la operación de inserción.

La primera etapa: verificación de restricción de unicidad, primero solicite  LOCK_S + LOCK_ORDINARY

La segunda etapa: Después de adquirir el bloqueo de la etapa 1 e insertarlo correctamente, hay un bloqueo GAP en la posición insertada: LOCK_INSERT_INTENTION, para evitar otros conflictos de claves únicas de inserción.

Después de insertar los nuevos datos: LOCK_X + LOCK_REC_NOT_GAP

Para la operación de inserción, si se produce un conflicto de restricción única, debe agregar S Bloqueo de tecla siguiente al índice único en conflicto. A partir de aquí, encontrará que incluso en el nivel de aislamiento de transacciones RC, también habrá un bloqueo de bloqueo de tecla siguiente, bloqueando así la concurrencia. Sin embargo, lo que el documento no dice es que para el índice único donde se detecta el conflicto, el hilo en espera necesita bloquear el siguiente registro después de obtener el Bloqueo S. El código fuente se usa para determinar la función row_ins_scan_sec_index_for_duplicate.

En segundo lugar, necesitamos la matriz de compatibilidad desbloqueada.

De la matriz de compatibilidad, podemos sacar las siguientes conclusiones:

No habrá conflictos entre las operaciones INSERT.

GAP, Next-Key bloqueará Insert.

GAP y Record, Next-Key no entrarán en conflicto.

Grabar y grabar, la siguiente clave entra en conflicto entre sí.

El bloqueo de inserción existente no impide que se agreguen bloqueos.

Los bloqueos GAP ya retenidos bloquearán el bloqueo de intención de inserción INSERT_INTENTION.

Además , se aplicarán bloqueos GAP para actualizar o eliminar registros inexistentes mediante un índice único.

análisis

Al comprender el conocimiento básico anterior, comenzamos a analizar el registro de interbloqueo:

T1: sess1 actualiza los datos a través de la clave única, dado que c2 = 4 no existe, la fila de efecto se devuelve como 0 y MySQL aplicará para el bloqueo GAP entre (3,6).

T2: La situación de sess2 es similar a la de sess1, y también se aplicará el bloqueo GAP entre (3,6) De la matriz de compatibilidad anterior, los dos bloqueos GAP no entrarán en conflicto.

T3: sess1 devuelve la fila de efecto como 0 de acuerdo con la declaración de actualización y ejecuta la operación de inserción. En este momento, es necesario solicitar un bloqueo de intención de inserción. El bloqueo GAP mantenido por la sesión sess2 entra en conflicto con el bloqueo de intención de inserción solicitado por sess1, y hay una espera.

índice uc2 de la tabla test.ty id trx 1863 lock_mode X bloquea el espacio antes de rec insertar intención en espera

T4: sess2 es similar a sess1, según la declaración de actualización, la fila de efecto se devuelve como 0 y se ejecuta la operación de inserción. El bloqueo de intención de inserción aplicado entra en conflicto con el bloqueo GAP mantenido por la declaración de actualización de sess1. sess1 (manteniendo el bloqueo de GAP), sess2 (manteniendo el bloqueo de GAP), sess1 (bloqueo de intención de inserción esperando la liberación de bloqueo de GAP de sess2) sess2 (bloqueo de intención de inserción esperando la liberación de bloqueo de GAP de sess1)  constituyen una espera circular, que conduce a un punto muerto.

2.6 Solución

Desde la perspectiva de la lógica de procesamiento del escenario empresarial, la empresa necesita enviar dos solicitudes, una actualización y una inserción para completar la lógica empresarial, que no es amigable y optimizada.

De hecho, podemos comunicarnos bien con los compañeros de desarrollo para confirmar la idempotencia del negocio, usar el método insertar en clave duplicada, insertar si no hay, actualizar si existe, una llamada puede completar la función de las dos operaciones anteriores y mejorar el rendimiento.

Tres, resumen

Finalmente, quiero hablar sobre la idea de resolver el problema del interbloqueo:

1. Tener un conocimiento básico sólido de cerraduras.

2. Es difícil juzgar la situación específica de ejecución de SQL basándose solo en el registro de interbloqueo Es necesario comunicarse con los compañeros de desarrollo para aclarar la lógica de SQL de ejecución empresarial y luego simular la prueba.

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