Bloqueo InnoDB

1. Qué es un candado.

El mecanismo de bloqueo se utiliza para administrar el acceso simultáneo a los recursos compartidos. InnoDB bloquea los datos a nivel de fila y también utiliza bloqueos en muchos otros lugares dentro de la base de datos, lo que permite el acceso simultáneo a muchos recursos diferentes.

2.bloqueo 与 pestillo

En la base de datos, tanto el candado como el pestillo se pueden llamar candados. Pero los dos tienen significados completamente diferentes, esta publicación de blog se centra principalmente en el bloqueo.

Los pestillos se denominan generalmente cerraduras shuan (cerraduras ligeras). Requiere un tiempo de bloqueo muy corto En InnoDB, los pestillos se pueden dividir en mutex (exclusión mutua) y rwlock (bloqueo de lectura y escritura). Su propósito es garantizar la corrección de los subprocesos simultáneos que operan recursos críticos y, por lo general, no existe un mecanismo de detección de interbloqueo.

El objeto de bloqueo es una transacción y se utiliza para bloquear objetos en la base de datos, como tablas, páginas y filas. Y el objeto de bloqueo se libera solo después de la confirmación o reversión de la transacción (el tiempo de liberación puede ser diferente para diferentes niveles de aislamiento), y el bloqueo tiene un mecanismo de detección de interbloqueo

 

3. Tipos de bloqueo en el motor de almacenamiento InnoDB

3.1 Implementar las siguientes dos cerraduras estándar a nivel de fila;

Bloqueo compartido (S Lock), que permite que las transacciones lean una fila de datos

Bloqueo exclusivo (X Lock), permite que las transacciones eliminen o actualicen una fila de datos

Compatibilidad de cerraduras exclusivas y cerraduras compartidas

La cerradura X es incompatible con cualquier cerradura, mientras que la cerradura S solo es compatible con la cerradura S. S y X son cerraduras de fila. La compatibilidad se refiere a la compatibilidad de la misma cerradura de fila. Además, InnoDB admite el bloqueo de granularidad múltiple, que permite que los bloqueos de transacciones en los niveles de fila y tabla existan simultáneamente. Para admitir operaciones de bloqueo en diferentes granularidades, InnoDB admite un método de bloqueo adicional llamado bloqueo por intención. Los bloqueos intencionales dividen los objetos bloqueados en varios niveles. Los bloqueos intencionales significan que la transacción espera bloquearse a un nivel más granular. Como se muestra en la figura siguiente, si desea agregar un bloqueo X al registro r, debe agregar el bloqueo de intención IX a la base de datos A, la tabla y la página, respectivamente, y finalmente agregar el bloqueo X al registro r. Si alguna parte provoca una espera, la operación debe esperar a que se complete el bloqueo de grano grueso.

InnoDB admite el diseño conciso de bloqueos de intención, y sus bloqueos de intención son bloqueos de intención a nivel de tabla. El propósito del diseño es principalmente revelar el tipo de bloqueo que se solicitará en la siguiente línea de una transacción.

Admite dos bloqueos de intención:

Bloqueo compartido intencional (bloqueo IS), las cosas quieren obtener un bloqueo compartido en ciertas filas de una tabla

Intento de bloqueo exclusivo (Bloqueo IX), las cosas quieren obtener bloqueos exclusivos en ciertas filas de una tabla

Dado que InnoDB admite bloqueos de nivel de fila, los bloqueos de intención no bloquean ninguna solicitud que no sean escaneos completos de la tabla. Por lo tanto, la compatibilidad de los bloqueos de intención a nivel de tabla y los bloqueos de nivel de fila se muestra a continuación.

4. Lectura constante sin bloqueo

Se refiere a InnoDB para leer los datos de la fila en la base de datos de tiempo de ejecución actual a través del control de versiones de varias filas. Si la fila de lectura está realizando una operación DELETE o UPDATE, entonces la operación de lectura no esperará a que se libere el bloqueo de la fila. Por el contrario, InnoDB leerá una instantánea de datos de la fila. La razón por la que se llama no La lectura de bloqueo es Porque no hay necesidad de esperar a que se libere el bloqueo X en la fila accedida. Los datos de instantánea se refieren a los datos de la versión anterior de la fila, que se completa con el segmento de deshacer, y el segmento de deshacer se usa para revertir los datos en la transacción, por lo que los datos de instantánea en sí no tienen gastos generales adicionales. Además, no es necesario bloquear la lectura de los datos de la instantánea, porque no es necesario que ninguna transacción modifique los datos históricos. Los datos instantáneos son en realidad la versión histórica antes de los datos de la fila actual. Un registro de fila puede tener varios datos instantáneos. Esta tecnología generalmente se denomina tecnología de múltiples versiones de filas. El control de concurrencia que trae esto se llama control de concurrencia de múltiples versiones ( MVCC).

En la configuración predeterminada de InnoDB, este es el método de lectura predeterminado, pero el método de lectura es diferente en diferentes niveles de aislamiento de transacciones. En el nivel de aislamiento predeterminado (RR), siempre lea los datos de la instantánea de la fila bloqueada al comienzo de la transacción y siempre lea el último número de instantánea de la fila bloqueada en el nivel RC

Por lo tanto, bajo el nivel de aislamiento de RC, se pueden leer los registros enviados por otras transacciones. En el nivel RR, los registros enviados por otras transacciones no se pueden leer

Además, debe tenerse en cuenta que InnoDB lee los datos de la fila, incluidas las lecturas actuales y las lecturas de instantáneas. Seleccione ... para actualizar; seleccione ... bloquear en modo compartir; son todas las lecturas actuales. En el nivel RR, se basan en las siguientes bloqueo de teclas. Resolver lectura fantasma y selección ordinaria ... es una lectura de instantánea, es decir, cuando se inicia la transacción, la primera instrucción de selección producirá un registro de instantánea ReadView, en la transacción actual, la siguiente consulta de selección sigue siendo esta registro de instantánea, por lo que la lectura fantasma se resuelve naturalmente para la lectura de instantánea. Para la solución de la lectura fantasma, hay una interpretación más detallada en la Sección 9.

5. Lectura de bloqueo consistente

En algunos casos, los usuarios deben bloquear explícitamente la operación de lectura de la base de datos para garantizar la coherencia de la lógica de los datos. InnoDB admite dos tipos de operaciones de lectura de bloqueo de lectura coherentes para declaraciones SELECT:

SELECCIONAR ... PARA UDATE: agregue el bloqueo exclusivo X, otras transacciones no pueden agregar ningún bloqueo a los registros que han sido bloqueados por X y deben esperar hasta que se libere el bloqueo X para continuar la operación de bloqueo

SELECCIONE ... BLOQUEO EN MODO COMPARTIDO: agregue un bloqueo compartido S, otras transacciones solo pueden agregar bloqueos S a los registros con bloqueos S, y los bloqueos X entrarán en el estado de bloqueo hasta que se libere el bloqueo S

6. Crecimiento personal y bloqueo

En la estructura de memoria del motor de almacenamiento InnoDB, hay un contador de incremento automático para cada tabla que contiene un valor de incremento automático. Al insertar en esta tabla, el contador se inicializa para ejecutar SELECT MAX (auto_inc_col) FROM t FOR UPDATE para obtener el valor del contador. La operación de inserción agregará 1 a la columna auto-creciente basada en este contador auto-creciente. Esta implementación se llama Bloqueo AUTO-INC. Es un mecanismo de bloqueo de tabla especial.Para mejorar el rendimiento de la inserción, el bloqueo no se libera después de que se completa una transacción, sino que se libera inmediatamente después de que se completa la instrucción SQL que inserta el valor auto-creciente. Aunque el bloqueo AUTO-INC mejora la eficiencia de las inserciones simultáneas hasta cierto punto, todavía existen algunos problemas de rendimiento. En primer lugar, el rendimiento de la inserción simultánea es deficiente y, en segundo lugar, la inserción de una gran cantidad de datos para INSERT ... SELECT afectará el rendimiento de la inserción, porque la inserción en otra transacción se bloqueará. A partir de la versión 5.1.22, InnoDB proporciona un mecanismo de implementación de crecimiento propio de mutex ligero, que mejora en gran medida el rendimiento de inserción de crecimiento propio.

Además, en InnoDB, la columna de autocrecimiento debe ser un índice y debe ser la primera columna del índice; de ​​lo contrario, se lanzará una excepción y myisam no necesita considerar problemas de concurrencia basados ​​en el autocrecimiento de bloqueo de tabla.

7. Cerraduras y llaves extranjeras

Las claves externas se utilizan principalmente para comprobar las restricciones de integridad referencial. En el motor de almacenamiento InnoDB, para una columna de clave externa, si no se muestra un índice en la columna, el motor de almacenamiento InnoDB le agrega automáticamente un índice, lo que puede evitar bloqueos de tabla. Para la inserción o actualización de valores de claves foráneas. Primero, debe consultar los registros en la tabla principal, es decir, la tabla principal SELECT. Pero para la operación SELECT de la tabla principal, no se usa el método de lectura consistente sin bloqueo, porque el problema de inconsistencia de datos ocurrirá de esta manera, y el método de bloqueo S-SELECT ... Si el candado X se ha agregado a la tabla principal en este momento, las operaciones en la tabla secundaria se bloquearán, como se muestra a continuación

En este ejemplo, las transacciones en las dos sesiones no han realizado operaciones COMMIT o ROLLBACK, y se bloqueará la operación de la sesión B. Esto se debe a que la tabla principal con id 3 ha agregado un bloqueo X en la sesión A, y esto cuando el el usuario en la sesión B necesita agregar un bloqueo S a la fila con el id 3 en la tabla principal, la operación INSERT se bloqueará. Si usa una lectura constante sin bloqueo al acceder a la tabla principal, la sesión B leerá que la tabla principal tiene un registro con id = 3, y puede insertarlo, pero si la sesión A envía algo, la tabla principal estará allí. no hay registro con id = 3. Los datos serán inconsistentes en las tablas padre e hijo.

8. Algoritmo de bloqueo

Tres algoritmos para bloqueos de filas:

  1. Bloqueo de registro: bloqueo de registro, el bloqueo en un registro de una sola fila. Bloquear los registros de índice Si la tabla InnoDB se crea sin ningún conjunto de índices, utilizará el índice de clave primaria implícita para bloquear.
  2. Bloqueo de espacio: Bloqueo de espacio, bloquea un rango, pero no incluye el registro en sí.
  3. Bloqueo de tecla siguiente: bloqueo de tecla de proximidad, bloqueo de espacio + bloqueo de registro, bloquea un rango y bloquea el registro en sí

Next-Key Lock es un algoritmo de bloqueo que combina Gap Lock y Record Lock. Bajo el algoritmo Next-Key Lock, InnoDB usa este algoritmo para consultas de fila. Por ejemplo, si hay un índice con cuatro valores de 10, 11, 13, 20, entonces el intervalo en el que el índice puede ser Bloqueo de tecla siguiente es (-∞, 10], (10, 11], ( 11, 13), (13, 20], (20, + ∞). El uso de la tecnología de bloqueo Next-Key Lock se denomina Next-Key Locking. Su propósito de diseño es resolver la lectura fantasma. Esta tecnología de bloqueo no bloquea un solo valor, pero un rango. Si la transacción T1 ha sido bloqueada por el bloqueo de tecla siguiente en los siguientes rangos (10,11], (11,13], cuando se inserta un nuevo registro 12, el rango bloqueado se convertirá en (10,11), (11,12), (12,13]. Sin embargo, cuando el índice de consulta contiene atributos únicos, InnoDB optimizará Next-Key Lock y lo degradará a Record Lock, es decir, solo bloqueará el índice en sí, no el rango.

Ejemplo: Cree la tabla t y ejecute la sesión en la tabla.

drop table if exists t;
create table t(a int primary key);
insert into t values (1);
insert into t values (2);
insert into t values (5);

Hay tres valores de 1, 2 y 5 en la tabla t. En el ejemplo anterior, a = 5 primero se bloquea con X en la sesión A. Como a es la clave principal, se agrega un bloqueo de registro a esta fila. de un bloqueo de espacio. De esta manera, insertar el valor de a = 4 en la sesión B no bloqueará, y se puede insertar y devolver inmediatamente, es decir, el bloqueo es degradado por el algoritmo Next-Key Lock al Record Lock , mejorando así la concurrencia.

Si es un índice normal, es otro caso.

create table z(a int,b int,primary key(a),key (b));
insert into z values (1,1);
insert into z values (3,1);
insert into z values (5,3);
insert into z values (7,6);
insert into z values (10,8);

会话A
begin;
select * from z where b = 3 for update;
这时通过索引列b进行查询,使用传统的Next-Key Locking 技术加锁,由于有两个索引,需要分别加锁
对于主键索引对a=5的索引上加Record Lock,对于普通索引,加的是Next-Key Lock,锁定范围是(1,3],
需要注意的是,Innodb会对普通索引的下一个键值加上gap lock,即还有一个辅助索引范围为(3,6]的锁


会话B
begin;
select * from z where a = 5 lock in share mode;  阻塞
a=5的列上有X锁,这里的S锁需要等待X锁的释放,所以会阻塞

会话C
begin;
insert into z values (4,2); 阻塞
insert into z values (6,5); 阻塞

主键插入4没问题,但是b=2的值在锁定的范围(1,3],需要等待
主键插入6没问题,但是b=5的值在锁定的范围(3,6],需要等待

会话D
begin;
insert into z values (8,6);
insert into z values (2,0);
insert into z values (6,7);
commit;
三条sql可以立即执行,不会被阻塞




 

Como se puede ver en el ejemplo anterior, la función de Gap Lock es evitar que múltiples transacciones inserten registros en el mismo rango y resolver el problema de la lectura fantasma.

En el motor InnoDB, para la operación INSERT, verificará si el siguiente registro del registro insertado está bloqueado. Si ya está bloqueado, la consulta no está permitida. Para el ejemplo anterior, la sesión A ha bloqueado el registro de b = 3 en la tabla z, es decir, el rango de (1,3) está bloqueado. En este momento, las siguientes inserciones en otras sesiones también causarán bloqueo. inserte en z valores (2,2); porque el registro de valor 2 se inserta en el índice ordinario b Cuando, detecta que se ha indexado el siguiente registro 3. Y cambia el valor de inserción al siguiente valor, puede ejecutarlo inmediatamente: insertar en valores z (2,0);

Por último, correspondiente al bloqueo de la clave única, Next-Key Lock se degrada a Record Lock. Solo existe en todas las columnas de índice únicas de la consulta. Si el índice único consta de varias columnas, y la consulta solo busca una de las múltiples columnas de índice únicas, entonces la consulta es en realidad de tipo de rango, no de tipo de punto, por lo que el bloqueo de tecla siguiente todavía se usa para bloquear.

9. Resolver lectura fantasma

La lectura fantasma se refiere a que debajo de la misma cosa, ejecutar la misma instrucción SQL dos veces seguidas puede llevar a resultados diferentes, y la segunda instrucción SQL puede devolver filas que no existían antes.

¿MVCC resuelve la lectura fantasma? La respuesta es que no está completamente resuelto. Para la lectura fantasma, debe comprender el concepto de "lectura actual" y "lectura instantánea". La lectura actual es la última versión de los datos leídos, la actualización común, insertar, eliminar y seleccionar ... para actualizar, seleccionar ... bloquear en modo compartir; estas son las lecturas actuales. La lectura de la instantánea se refiere a que MVCC lee de ReadView, por lo que inevitablemente no verá las filas recién insertadas o eliminadas, por lo que el problema de la lectura fantasma se resuelve de forma natural. Para la lectura actual, MVCC no puede resolverlo, y se usa Next-Key Lock . Resolver.

seleccione * del usuario donde id <10 para la actualización; Consulta de rango, la columna de id es la clave principal, use Next-Key Lock para bloquear todo el rango de id <10, otras transacciones no pueden insertar datos con id <10, evitando así la lectura fantasma

El RR especificado en el estándar SQL no puede eliminar la lectura fantasma, pero el RR de mysql puede resolver la lectura fantasma mediante el bloqueo de Next-Key Lock. En el nivel de aislamiento predeterminado RR, InnoDB usa el mecanismo de Next-Key Locking para evitar la lectura fantasma. Record Lock se usa en nivel, por lo que no se puede evitar la lectura fantasma.

Además, la verificación de unicidad se puede implementar en el nivel de la aplicación a través del mecanismo de bloqueo de siguiente clave. Por ejemplo, seleccione * de la tabla donde col = xx se bloquea en el modo de compartir; si no se pueden encontrar los datos, realice la operación de inserción insertar en los valores de la tabla (...). Entonces, esta pieza de datos solo se puede insertar una vez, y la escritura simultánea hará que otras transacciones entren en un punto muerto y generen una excepción. Al final, solo una cosa se escribió con éxito, una típica inserción idempotente.

10. El problema de la cerradura

El requisito de aislamiento de la transacción se logra a través del mecanismo de bloqueo, de modo que la transacción pueda funcionar simultáneamente, el bloqueo mejora la concurrencia y también trae problemas potenciales. Debido a los requisitos de aislamiento de transacciones, los bloqueos solo causarán tres problemas. Si se puede evitar que ocurran estas tres situaciones, no producirán excepciones concurrentes.

Lectura sucia (Lectura sucia): La transacción cambia los registros de fila en el grupo de búfer sin confirmar. Los datos sucios se refieren a datos no comprometidos, si se leen datos sucios, es decir, una transacción lee los datos no comprometidos de otra transacción, lo que obviamente viola el aislamiento de la base de datos. Las lecturas sucias no son comunes en el entorno de producción. La condición para que ocurran lecturas sucias es que el nivel de aislamiento de la transacción sea RU (LECTURA NO COMPROMETIDA). En la actualidad, la mayoría de las bases de datos están diseñadas para ser al menos RC (LECTURA COMPROMETIDA). El nivel de aislamiento de transacciones predeterminado de InnoDB es RR (READ REPEATABLE). El aislamiento de lectura sucia parece inútil, pero en algunos casos especiales aún puede establecer el nivel de aislamiento de la transacción en RU, como el nodo esclavo en el entorno de replicación, y la consulta en este nodo no necesita ser un valor de retorno particularmente preciso.

Lectura no repetible: se refiere a leer el mismo conjunto de datos varias veces en el mismo objeto. Cuando esta transacción no termina, otra transacción también accede al mismo conjunto de datos. Y realizada la operación MDL, por lo tanto, entre los dos datos leídos en la primera transacción, debido a la modificación de la segunda transacción, los datos leídos dos veces pueden ser diferentes. Esto ocurre cuando los datos leídos por dos operaciones de lectura en una transacción son diferentes, lo que se denomina lectura no repetible. La diferencia entre lectura no repetible y lectura sucia es: la lectura sucia lee los datos no confirmados de otras transacciones y la lectura no repetible lee los datos enviados por otras transacciones, lo que viola los requisitos de consistencia de la base de datos. En general, la lectura no repetible es aceptable, porque lee los datos que ya se han enviado, lo que no causará grandes problemas por sí solo. Por lo tanto, muchos proveedores de bases de datos (Oracle, Microsoft SQL Server) establecen el nivel de aislamiento predeterminado de sus transacciones de base de datos en RC, lo que permite lecturas no repetibles bajo este nivel de aislamiento. En el motor de almacenamiento InnoDB, el problema de las lecturas no repetibles se evita utilizando el algoritmo Next-Key Lock. El problema de la lectura no repetible se define como lectura fantasma en la documentación oficial de mysql. Bajo el algoritmo Next-Key Lock, para el escaneo de índices, no solo se bloquea el índice escaneado, sino también el rango (espacio) cubierto por estos índices. Por lo tanto, no se permiten inserciones dentro de este rango. Esto evita el problema de lectura no repetible causado por otras transacciones que insertan datos en este rango. Por lo tanto, el nivel de aislamiento de transacciones predeterminado del motor de almacenamiento InnoDB es RR, y el algoritmo Next-Key Lock se utiliza para evitar lecturas no repetibles.

Actualización perdida: la operación de actualización de una transacción será sobrescrita por la operación de actualización de otra transacción, lo que resultará en una inconsistencia de datos. P.ej

  1. La transacción T1 actualiza el registro de fila r a v1, pero T1 no se confirma.
  2. Al mismo tiempo, la transacción T2 actualiza el registro de fila r a v2, la transacción T2 no se confirma
  3. La transacción T1 está comprometida.
  4. La transacción T2 está comprometida.

Sin embargo, bajo cualquier nivel de aislamiento de la base de datos actual, no conducirá a la pérdida de actualización en el sentido teórico de la base de datos. Esto se debe a que incluso bajo el nivel de aislamiento RU, para las operaciones DML, es necesario bloquear filas u otros objetos de grano grueso. Por lo tanto, en el paso 2 anterior, la transacción T2 no puede actualizar el registro de fila r, y se bloqueará hasta que se confirme T1. Aunque el problema de las actualizaciones faltantes se puede prevenir en la base de datos, existe otro significado lógico de las actualizaciones faltantes en las aplicaciones de producción, y el problema no es causado por la base de datos en sí. En pocas palabras, si ocurre la siguiente situación, se producirá una actualización perdida.

  1. La transacción T1 consulta una fila de datos, la coloca en la memoria local y la muestra a un usuario de terminal Usuario1.
  2. La transacción T2 consulta la misma fila de datos y muestra los datos obtenidos al usuario final User2.
  3. User1 modifica esta fila, actualiza la base de datos y la envía.
  4. User2 modifica esta fila de registros, actualiza la base de datos y la envía.

Obviamente la operación de actualización del Usuario1 se pierde en este proceso, para evitar el problema de las actualizaciones faltantes, es necesario realizar la operación de transacción en este caso serializada en lugar de la operación síncrona, es decir, en el paso 1 anterior, se realiza un bloqueo exclusivo X agregado a los registros que se leen más, y también se agrega un candado exclusivo X a la operación del paso 2. De esta forma, una transacción debe esperar hasta que se complete la operación de confirmación de otra transacción antes de que pueda continuar.

11. Bloqueo

Debido a la relación de compatibilidad entre diferentes bloqueos, a veces el bloqueo de una transacción debe esperar a que el bloqueo de otra transacción libere los recursos que ocupaba. Esto es bloqueo. El bloqueo no es algo malo. Es para garantizar que las transacciones se puedan ejecutar. al mismo tiempo y normalmente. En el motor de almacenamiento de InnoDB, el parámetro innodb_lock_wait_timeout se usa para controlar el tiempo de espera (predeterminado 50 s), y innodb_rollback_on_timeout se usa para establecer si se debe deshacer la transacción en curso durante el tiempo de espera (apagado predeterminado, lo que significa que no se ejecutará). El parámetro innodb_lock_wait_timeout es dinámico y se puede ajustar mientras se ejecuta la base de datos mysql set @@ innodb_lock_wait_timeout = 60;

Innodb_rollback_on_timeout es estático y no se puede modificar cuando se reinicia. Cuando se agota el tiempo de espera, mysql arrojará un error 1205. Lo que debe tenerse en cuenta es que, por defecto, InnoDB no revertirá la excepción de error causada por el tiempo de espera, de hecho, InnoDB no revertirá la excepción en la mayoría de los casos. Si se produce una excepción después de la mitad de la transacción, pero no se realiza ninguna confirmación o reversión, esta situación es muy peligrosa, por lo que el usuario debe determinar si se requiere una confirmación o una reversión. Luego continúe con el siguiente paso.

12. Punto muerto

El punto muerto se refiere al fenómeno de esperar el uno al otro debido a la contención de los recursos del bloqueo durante la ejecución de dos o más transacciones. Si no hay fuerza externa, la transacción no podrá avanzar y el problema del punto muerto está resuelto. Lo simple es que no hay espera, cualquier espera se convierte en reversión y la transacción se reinicia. Esto puede solucionar el punto muerto, pero el entorno en línea provocará una degradación del rendimiento. En casos graves, ni siquiera se puede realizar una transacción. Esto trae problemas más graves que los puntos muertos, ya que es difícil encontrar y desperdiciar recursos.

La forma más sencilla de resolver el interbloqueo es el tiempo de espera, es decir, dos transacciones se esperan entre sí. Cuando un tiempo de espera supera un cierto umbral, una de las transacciones se revierte y la otra continúa. Innodb_lock_wait_timeout se utiliza para establecer el período de tiempo de espera. en InnoDB. Aunque el mecanismo de tiempo de espera es simple, solo se maneja revertiendo la transacción después del tiempo de espera, o seleccionando el objeto a revertir de acuerdo con el orden FIFO. Si el peso de la transacción de tiempo de espera es relativamente grande, por ejemplo, la transacción actualiza muchas filas y ocupa más undi log, entonces el método FIFO no es apropiado. Porque revertir esta transacción puede llevar más tiempo que otra transacción.

Por lo tanto, además del mecanismo de tiempo de espera, las bases de datos actuales generalmente usan métodos de gráfico de espera (gráfico de espera) para la detección de puntos muertos. Este es un enfoque más proactivo que la solución anterior. InnoDB también utiliza este enfoque. Wait-for graph requiere que la base de datos almacene los siguientes dos tipos de información:

  1. Lista vinculada de información bloqueada
  2. Lista de espera de transacciones

Se puede construir un gráfico a través de la lista vinculada anterior.Si hay un bucle en este gráfico, representa un punto muerto, por lo que los recursos se esperan unos a otros. En el gráfico de espera, las transacciones son nodos en el gráfico. En la figura, la transacción T1 apunta al lado T2 se define como

  1. La transacción T1 espera los recursos ocupados por la transacción T2
  2. La transacción T1 finalmente espera los recursos ocupados por T2, es decir, espera el mismo recurso entre transacciones, y la transacción T1 ocurre después de la transacción T2

Veamos un ejemplo, la siguiente figura muestra el estado de la transacción y la información de bloqueo

En las listas de espera de transacciones, puede ver que hay 4 transacciones t1, t2, t3, t4, por lo que debería haber 4 nodos en el gráfico de espera. La transacción t2 ocupa el bloqueo X en la fila1 y la transacción t1 ocupa el bloqueo s en la fila2. La transacción t1 necesita esperar los recursos de la fila1 en la transacción t2, por lo que hay una ventaja en el gráfico de espera del nodo t1 al t2. La transacción t2 necesita esperar los objetos de la fila2 ocupados por las transacciones t1 y t4, por lo que hay un borde desde el nodo t2 a los nodos t1 y t4. También hay bordes desde t3 a los nodos t1, t2 y t4. Por lo tanto, el gráfico de espera final se muestra en la siguiente figura. Hay un bucle (t1, t2), por lo que hay un punto muerto. A través de la introducción anterior, podemos encontrar que el gráfico de espera es un mecanismo de detección de interbloqueo más activo. Cuando cada transacción solicita un bloqueo y espera, determinará si hay un bucle. Si hay un punto muerto, InnoDB generalmente opta por revertir la transacción con la menor cantidad de deshacer. La detección de interbloqueo del gráfico de espera generalmente se implementa mediante el algoritmo de profundidad primero. Antes de la versión 1.2 de InnoDB, se adoptó el método recursivo. A partir de la versión 1.2, se ha optimizado. La recursividad se implementa de manera no recursiva, lo que mejora aún más InnoDB El rendimiento del motor de almacenamiento.

13. Probabilidad de punto muerto

Los interbloqueos deben ocurrir muy raramente, si ocurren con frecuencia, el sistema no se puede utilizar. Además, el número de interbloqueos es menor que esperar, porque se necesitan al menos 2 esperas para producir un interbloqueo.

n: número de subprocesos r: número de transacciones R: recopilación de datos operativos. A partir de la fórmula se encuentra que nr << R, por lo que la probabilidad de un punto muerto de transacción es muy baja. Al mismo tiempo, la probabilidad de que se produzca un punto muerto en la transacción está relacionada con los siguientes factores:

  1. El número de transacciones en el sistema (n), cuanto mayor es el número, mayor es la probabilidad de bloqueo.
  2. El número de cada operación de transacción (r), cuanto mayor sea el número de cada operación de transacción, mayor será la probabilidad de un punto muerto.
  3. El conjunto de datos de operación (R), menor es la probabilidad de bloqueo.

Los ejemplos de interbloqueo son los siguientes: A espera a B y B espera a A. Este tipo de problema de interbloqueo se denomina interbloqueo AB-BA.

En la operación anterior, la transacción B arroja un error de interbloqueo 1213. La razón es que los recursos de AB se están esperando entre sí. InnoDB detectará la mayoría de los interbloqueos y no requiere intervención humana. Sin embargo, en el ejemplo anterior, la transacción B arroja una excepción de interbloqueo , A El recurso registrado como 2 se obtuvo inmediatamente. De hecho, la transacción B se revertió, de lo contrario la transacción A no podría obtener el recurso. El contenido anterior dice que InnoDB no revertirá la mayoría de las excepciones, excepto los puntos muertos. Después de descubrir el punto muerto, InnoDB inmediatamente deshace la transacción. Por lo tanto, si el error 1213 se detecta en la aplicación, no es necesario revertir la aplicación.

14. Mejora de bloqueo

Medios para reducir la granularidad del bloqueo actual. Por ejemplo, una base de datos puede actualizar 1000 bloqueos de fila de una tabla a un bloqueo de página, o actualizar un bloqueo de página a un bloqueo de tabla. Si los bloqueos se consideran un recurso poco común en el diseño de la base de datos y desea evitar la sobrecarga de los bloqueos, la escalada de bloqueos se producirá con frecuencia en la base de datos. InnoDB no tiene el problema de la escalada de bloqueos, ya que no genera bloqueos de fila en base a cada registro, por el contrario, gestiona bloqueos en función de cada página a la que accede cada transacción, utilizando un método de mapa de bits, por lo que no importa una transacción bloquea el La página Un registro en sigue siendo varios registros. La sobrecarga es constante.

Suponiendo que una tabla tiene 3 millones de páginas de datos y cada página tiene 100 registros, hay 300 millones de registros en total. Si una transacción ejecuta una instrucción SQL que actualiza toda la tabla, necesita agregar X bloqueos a todos los registros, y los objetos de bloqueo se generan de acuerdo con cada registro de fila, y cada bloqueo ocupa 10 bytes. Solo la administración de bloqueos requiere casi 3G de memoria. El motor de almacenamiento InnoDB se bloquea según la página, utilizando un método de mapa de bits. Suponiendo que la información de bloqueo almacenada en cada página ocupa 30 bytes, el objeto de bloqueo solo necesita 90 MB de memoria. Se puede ver que la brecha de costos entre los dos para los recursos de bloqueo es grande

Finalmente: la mayor parte del contenido de este artículo se compila a partir de la segunda edición del motor de almacenamiento InnoDB, el iniciado de la tecnología MySql. Algunos se refieren a esta publicación de blog https://blog.csdn.net/v123411739/article/details/106893197 .

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/csdnbeyoung/article/details/113934894
Recomendado
Clasificación