Un artículo para comprender en detalle los bloqueos de filas, los bloqueos de tablas y los bloqueos de espacios de MySQL

Listo para trabajar

Crear tabla tb_innodb_lock

eliminar tabla si existe test_innodb_lock; 
CREAR TABLA test_innodb_lock ( 
    a INT (11), 
    b VARCHAR (20) 
) ENGINE INNODB DEFAULT charset = utf8; 
insertar en test_innodb_lock valores (1, 'a'); 
insertar en test_innodb_lock valores (2, 'b'); 
insertar en test_innodb_lock valores (3, 'c'); 
insertar en test_innodb_lock valores (4, 'd'); 
insertar en test_innodb_lock valores (5, 'e');

Crear índice

crear el índice idx_lock_a en test_innodb_lock (a); 
crear el índice idx_lock_b en test_innodb_lock (b);

Demostración de bloqueo de MySQL

  • Primero cambie la transacción de confirmación automática a confirmación manual:set autocommit=0;

  • Iniciamos dos ventanas de sesión A y B, simulando una agarrando la cerradura y la otra bloqueándose sin agarrar.

Bloqueo de fila (escritura y lectura)

  • Una ejecución de ventana

actualizar test_innodb_lock set b = 'a1' donde a = 1;
SELECCIONAR * de test_innodb_lock;

1.png

Podemos ver el resultado actualizado en la ventana A

  • Ejecución de la ventana B

SELECCIONAR * de test_innodb_lock;

2.png

Podemos ver que la ventana B no puede ver los resultados actualizados, pero aún se ven los datos antiguos, debido a que el registro de a = 1 fue bloqueado por la instrucción SQL ejecutada por la ventana A y la operación de confirmación no se ejecutó. Entonces, la ventana B todavía ve los datos antiguos. Esta es la "lectura confirmada" en el nivel de aislamiento de MySQL.

  • La ventana A ejecuta la operación de confirmación

COMETER;


  • Consulta de la ventana B

SELECCIONAR * de test_innodb_lock;

3.png

En este momento, encontramos que la ventana B ha leído los datos más recientes.

Bloqueo de fila (escribir y escribir)

  • La ventana A realiza la actualización de un registro = 1

actualizar test_innodb_lock set b = 'a2' donde a = 1;

En este momento, no hay confirmación, y la ventana A mantiene el bloqueo.

  • La ventana B también actualiza el registro de a = 1

actualizar test_innodb_lock set b = 'a3' donde a = 1;

4.png

Como puede ver, la ventana B se ha bloqueado porque la ventana A aún no ha ejecutado el compromiso y aún mantiene el bloqueo. La ventana B no puede agarrar la cerradura registrada en la fila a = 1, por lo que se ha bloqueado esperando.

  • La ventana A ejecuta la operación de confirmación

COMETER;

  • Cambios en la ventana B

5.png

Puede ver que la ventana B se ha ejecutado correctamente en este momento

Bloqueo de mesa

Cuando un índice falla, el bloqueo de fila se actualizará a un bloqueo de tabla Uno de los métodos para el fallo de índice es cambiar el índice de forma automática o manual. El campo a en sí es un número entero, agregamos comillas, se convierte en una Cadena, esta vez el índice no será válido.

  • La ventana A actualiza el registro de a = 1

actualizar test_innodb_lock set b = 'a4' donde a = 1 o a = 2;

  • La ventana B actualiza el registro de a = 2

actualizar test_innodb_lock set b = 'b1' donde a = 3;

6.png

En este momento, se descubrió que aunque las filas actualizadas de la ventana A y B eran diferentes, la ventana B todavía estaba bloqueada porque el índice de la ventana A falló, lo que provocó que el bloqueo de fila se actualizara a bloqueo de tabla, bloqueando toda la tabla y la ventana de índice. B está bloqueado.

  • La ventana A ejecuta la operación de confirmación

COMETER;

  • Cambios en la ventana B

7.png

Puede ver que la ventana B se ha ejecutado correctamente en este momento

Bloqueo de espacios

  • ¿Qué es un bloqueo de espacio?

Cuando usamos condiciones de rango para consultar datos, InnoDB bloqueará los datos en este rango. Por ejemplo, hay 4 datos con id: 1, 3, 5 y 7, buscamos datos en el rango de 1-7. Entonces 1-7 se bloqueará. 2, 4 y 6 también están en el rango de 1-7, pero estos registros de datos no existen, estos 2, 4 y 6 se denominan huecos.

  • El daño del bloqueo de brecha

Al buscar en el rango, se bloquearán todos los datos de todo el rango. Incluso algunos datos que no existen en este rango se bloquearán de forma inocente. Por ejemplo, quiero insertar 2 en 1, 3, 5 y 7, esta vez 1 -7 está bloqueado y 2 no se puede insertar en absoluto. En algunos escenarios, tendrá un gran impacto en el rendimiento.

  • Demostración de bloqueo de espacios

Primero modificamos el valor del campo a a 1, 3, 5, 7, 9

  • La ventana A actualiza los datos en el rango a = 1 ~ 7

actualizar test_innodb_lock set b = 'b5' donde a> 1 y a <7;

  • La ventana B inserta datos en a = 2

insertar en test_innodb_lock valores (2, "b6");

8.png

En este momento, se encuentra que la operación de actualización a = 2 en la ventana B ha estado esperando, porque los datos en el rango de 1 ~ 7 están bloqueados por el espacio y bloqueados. Solo cuando la ventana A ejecuta el compromiso, la ventana B a = 2 puede la actualización tener éxito

Análisis de bloqueo de filas

  • Ejecutar comandos de análisis SQL

mostrar el estado como 'innodb_row_lock%';

9.png

  • Descripción de nombre de variable

    • Innodb_row_lock_current_waits: el número de bloqueos en espera actualmente.

    • Innodb_row_lock_time: el período de tiempo desde el inicio del sistema hasta el bloqueo actual.

    • Innodb_row_lock_time_avg: el tiempo promedio que se pasa esperando el bloqueo cada vez.

    • Innodb_row_lock_time_max: el tiempo más largo que tarda la cerradura en esperar desde que se inicia el sistema.

    • Innodb_row_lock_waits: el número total de esperas para bloqueos después de que se inició el sistema hasta ahora.

Al final

Gracias a todos por ver aquí, el artículo tiene deficiencias, y son bienvenidos a señalar; si creen que está bien escrito, por favor denme el visto bueno.


Supongo que te gusta

Origin blog.51cto.com/14849432/2542676
Recomendado
Clasificación