Bloqueo de espacios de MySQL

Hola, soy dios-jiang ~

Siguiendo el bloqueo de fila de MySQL en el artículo anterior, compartí el análisis de bloqueo de varias situaciones comunes bajo el nivel de aislamiento RC. Esta vez compartiré el bloqueo de brecha de MySQL y analizaré el análisis de bloqueo de varias situaciones comunes bajo el nivel de aislamiento RR.

create table `test`(
  `id` int(11) NOT NULL,
  `a` int(11) NOT NULL,
  `b` int(11) NOT NULL,
  `c` int(11) NOT NULL,
  PRIMARY KEY(`id`),
  UNIQUE KEY unix_key('a'),
  KEY ix_key(`b`)
)ENGINE=InnoDB;

insert into test values(0,0,0,0),(5,5,5,5),(10,10,10,10),(20,20,20,20);

Cree una tabla de prueba, id es la clave principal, a es un índice único, b es un índice normal y c no es un índice.

Ahora suponga que está en el nivel de aislamiento RC, hagamos un experimento para ver:

Transacción A Transacción B
establecer sesión transaction_isolation = 'READ-COMMITTED'; establecer sesión transation_isolation = 'READ-COMMITTED';
comenzar;
seleccione * de la prueba donde b = 5 para actualizar;
返回 : (5,5,5,5)
comenzar;
insertar en los valores de prueba (6,5,5,5);
cometer;
seleccione * de la prueba donde b = 5 para la actualización;
返回 : (5,5,5,5) , (6,5,5,5)
cometer;

Del experimento anterior, bajo el nivel de aislamiento RC, la transacción A agrega un bloqueo X a la fila de b = 5, pero el campo b de un nuevo registro insertado por la transacción B también es 5, y luego b se puede encontrar en la transacción A = 5 Hay dos registros, esto produce una "lectura fantasma".

En otras palabras, la lectura fantasma se refiere a cuando el mismo rango se consulta dos veces antes y después de una transacción, la última consulta ve las filas que no se vieron en la consulta anterior.

¿Por qué hay una lectura fantasma?

Analicemos la situación de bloqueo del nivel de aislamiento RC + índice ordinario b en este momento:

img

Se puede ver que bajo el nivel de aislamiento RC, el registro de b = 5 tiene bloqueo X, pero no hay bloqueo en el espacio de (0,5) y (5,10), por lo que se pueden insertar nuevos datos en este brecha.

Ahora puedo responder por qué hay una lectura fantasma. El motivo de la lectura fantasma es que el bloqueo de fila solo puede bloquear la fila, pero la acción de insertar un nuevo registro es actualizar el "espacio" entre los registros. Por lo tanto, para resolver el problema de las lecturas fantasma, InnoDB introdujo un nuevo bloqueo en el nivel de aislamiento RR, que es el bloqueo de espacio (Gap Lock).

Lo anterior habla de cómo se genera la lectura fantasma e InnoDB introduce el bloqueo de brecha para resolver la situación de lectura fantasma Luego, analiza el análisis de bloqueo del nivel de aislamiento RR.

Análisis de bloqueo (el siguiente valor predeterminado es el nivel de aislamiento RR y todos se leen actualmente)

Aquí he seleccionado tres situaciones comunes bajo el nivel de aislamiento RC para analizar cómo se bloquea SQL:

  • Nivel de aislamiento RR, donde el campo no tiene índice
  • Nivel de aislamiento RR, donde el campo tiene un índice ordinario
  • Nivel de aislamiento RR, donde el campo tiene un índice único

La estructura de la tabla que se muestra a continuación es la estructura al principio del artículo, y los datos son mi imaginación personal.

Nivel de aislamiento RR + sin índice

img

Como se muestra en la figura anterior, el bloqueo GAP se agrega al campo c (infinito negativo, 0), (0, 5), (5, 10), (10, 20), (20, infinito positivo). Pero bajo el nivel de aislamiento RR, todos usamos el bloqueo de la siguiente tecla (bloqueo de fila + bloqueo de espacio) de forma predeterminada, por lo que todos por defecto abrimos a la izquierda y a la derecha cerrada.

Como se muestra en la figura anterior, todos los registros tienen bloqueos X y también se agregan bloqueos GAP. Por lo tanto, si esta tabla no se ha confirmado durante la ejecución de select * from test donde c = 5 para la actualización, cualquier otra operación bloqueada será bloqueada, excepto las lecturas de instantáneas sin bloqueos. Si este es el caso en línea, lo será. algo muy aterrador.

Resumen: Bajo el nivel de aislamiento RR, la lectura actual de un campo de condición no indexado no solo agregará un bloqueo X a cada registro, sino que también agregará un bloqueo GAP. Nuevamente, las operaciones actuales de lectura o inserción / actualización / eliminación deben agregar un índice.

Nivel de aislamiento RR + índice normal

img

Como se muestra en la figura anterior, el campo de índice común b = 10 agrega X bloqueos a dos registros y agrega X bloqueos a dos registros del árbol de índice agrupado. GAP bloquea el rango de b (5, 10), (10, 10), (10, infinito positivo). Por lo tanto, los bloqueos de bloqueo de la siguiente tecla son (5,10], (10,10], (10, infinito positivo). Durante el período, siempre que b esté dentro del rango de bloqueo de la siguiente tecla, todas las actualizaciones serán obstruido.

Por ejemplo: insertar en los valores de prueba (6,6,6,6) se bloqueará porque el bloqueo de espacio del nivel de aislamiento RR bloquea el "espacio" entre registros, por lo que la operación se bloqueará.

Nivel de aislamiento RR + índice único

El caso del índice único es el más simple, porque no importa si es el nivel de aislamiento RC o el nivel de aislamiento RR, el índice único solo puede encontrar un registro, solo agrega un bloqueo X al registro de fila correspondiente y desaparece.

¿Por qué está pasando esto?

Porque el propósito del bloqueo GAP es evitar que la misma transacción se lea dos veces seguidas y luego las dos lecturas sean inconsistentes. Si se puede garantizar que el campo es único (índice único), de hecho, como máximo, solo un registro puede satisfacer la condición, por lo que el bloqueo GAP nunca aparecerá al consultar el índice único.

Se puede entender que la situación de bloqueo de RR + índice único y RC + índice único es la misma.

para resumir

  • Esta vez, compartí la situación de la lectura fantasma bajo el nivel de aislamiento RC, y luego analicé por qué hay lectura fantasma.
  • Para resolver las lecturas fantasmas, InnoDB introdujo bloqueos GAP en RR, que forma el bloqueo de la siguiente tecla con bloqueos de fila.
  • Analizó la situación de bloqueo de tres situaciones comunes.

Nota especial: el bloqueo de la siguiente tecla introducido por InnoDB solo resuelve la lectura fantasma de las lecturas instantáneas, pero no resuelve la lectura fantasma de las lecturas actuales.

De hecho, el bloqueo de la siguiente tecla resuelve la lectura fantasma de la lectura de instantáneas. Una gran parte de la razón se debe a deshacer el registro y MVCC. Permítanme dejar un suspenso aquí. Me tomaré el tiempo para escribir sobre el intercambio de MVCC y compartir eso.

Referencia

  • "MySQL 45 Conferencias" Lin Xiaobin
  • "Análisis del procesamiento de bloqueos MySQL" He Dengcheng

Supongo que te gusta

Origin blog.csdn.net/weixin_37686415/article/details/115031762
Recomendado
Clasificación