Comprensión profunda de bloqueos mysql y mvcc

Base

1 Explicación de bloqueo: elementos esenciales de la entrevista - bloqueo de fila, bloqueo de tabla - la diferencia y conexión entre bloqueo optimista y bloqueo pesimista

2 Explicación del mecanismo mvcc (cómo lograr varios niveles de aislamiento): fundamento de la base de datos (4) Principio de implementación de Innodb MVCC

Justo después de leer los dos artículos anteriores, puede haber muchas dudas. Aquí hay algunas dudas que resolví por mí mismo:

1 ¿Cómo previene el nivel rr la lectura fantasma?

"RR" es la abreviatura de "Lectura repetible" (lectura repetible), que es uno de los cuatro niveles de aislamiento estándar de la base de datos, y los otros tres son "Read Uncommitted" (lectura no confirmada), "Read Committed" (lectura confirmada). ) ) y "Serializable". Los diferentes niveles de aislamiento proporcionan un control de simultaneidad diferente, lo que puede generar un compromiso entre "coherencia de datos" y "rendimiento de simultaneidad".

El nivel de aislamiento de lectura repetible (Lectura repetible, RR) garantiza que los resultados de leer los mismos datos varias veces en una transacción sean consistentes, es decir, las transacciones en este nivel no verán otras transacciones modificando los datos. Esto evita el problema de las "lecturas no repetibles", donde una transacción ve datos diferentes en dos momentos diferentes cuando lee la misma fila de datos.

Sin embargo, incluso bajo el nivel de aislamiento de RR, puede haber un problema de "lectura fantasma" (Lectura fantasma). La lectura fantasma se refiere a la inconsistencia entre los resultados de la primera consulta y la última consulta durante una transacción. Este fenómeno no se debe a que los valores de los registros que se están leyendo sean cambiados por otras transacciones, sino a que algunos registros son insertados o eliminados por otras transacciones, lo que hace que veamos registros "fantasmas".

La forma más importante de evitar la lectura fantasma es utilizar el nivel más alto de nivel de aislamiento: serialización (serializable). En el nivel de serialización, las transacciones se ejecutan completamente en serie y, naturalmente, no hay problemas de lectura fantasma. Pero este nivel de aislamiento conlleva una gran penalización en el rendimiento de la concurrencia.

En la práctica, algunos sistemas de bases de datos (como el motor de almacenamiento InnoDB de MySQL) utilizarán "Next-Key Locking" para evitar la lectura fantasma en el nivel de RR. Next-Key Locking es una estrategia de bloqueo que no solo bloquea los registros del índice a los que accede la consulta, sino que también bloquea un "espacio" (Bloqueo de espacio) en el índice, lo que evita que otras transacciones inserten nuevos datos en el registro "espacio". , evitando así la generación de lecturas fantasma.

Nota: La estrategia de bloqueo con la tecla siguiente puede provocar un aumento de los conflictos de bloqueo, lo que puede reducir el rendimiento de la simultaneidad. En aplicaciones prácticas, es necesario sopesar el uso de acuerdo con la situación real.

2 bloqueo siguiente (bloqueo de llave profesional) y bloqueo de espacio (bloqueo de espacio)

la diferencia entre los dos

Tanto Next-Key Locking como Gap Locking son técnicas para sistemas de administración de bases de datos (como el motor InnoDB de MySQL) para evitar la lectura fantasma bajo el nivel de aislamiento de lectura repetible (RR). Todos implican una especie de "bloqueo de rango" de datos, es decir, no solo bloquean los registros a los que realmente se accede, sino que también bloquean la "brecha" entre registros. La principal diferencia entre los dos es la granularidad del bloqueo.

  1. Bloqueo de tecla siguiente : El bloqueo de tecla siguiente es el método de bloqueo de fila predeterminado de InnoDB. Es un bloqueo de combinación, que incluye bloqueo de fila (bloqueo de registro) y bloqueo de espacio (bloqueo de espacio). Específicamente, si una transacción T1 accede a un registro de índice R, entonces el bloqueo de clave siguiente bloqueará la "brecha de valor clave" de R y R mismo. De esta manera, no solo se evita que otras transacciones modifiquen R, sino que también se evita que otras transacciones inserten nuevos registros en la brecha de valor-clave de R. Next-Key Locking puede prevenir efectivamente la lectura fantasma.

  2. Bloqueo de espacios : el bloqueo de espacios solo bloquea los espacios entre los registros del índice, no los registros en sí. Por ejemplo, si una transacción T1 accede a los registros de índice R1 y R2, Gap Locking bloqueará la brecha entre R1 y R2, pero no bloqueará R1 y R2. Esto significa que otras transacciones pueden modificar el contenido de R1 y R2, pero no pueden insertar nuevos registros entre R1 y R2. Gap Locking se utiliza principalmente para lograr la coherencia de lectura y evitar lecturas fantasma, pero no evita lecturas no repetibles.

El bloqueo de tecla siguiente es más conservador, lo que proporciona garantías de coherencia de datos más sólidas, pero puede reducir el rendimiento de la simultaneidad. Gap Locking es más indulgente, ya que permite la modificación simultánea de los registros existentes, pero aún evita la lectura fantasma. En aplicaciones prácticas, se debe seleccionar una estrategia de bloqueo adecuada según las necesidades específicas.

Usar el bloqueo de teclas puede resolver perfectamente el problema de la lectura fantasma. El entrevistador preguntó, ¿es realmente perfecto?

Resumen: perfecto en seguridad pero defectuoso en rendimiento

"Perfecto" podría ser una declaración demasiado categórica, porque incluso el uso de un bloqueo de teclas no resuelve todos los problemas de simultaneidad e introduce una sobrecarga adicional.

El bloqueo de teclas de proximidad es un bloqueo utilizado por InnoDB para evitar la lectura fantasma por debajo del nivel de aislamiento de lectura repetible. Puede evitar que se inserten nuevos registros en un cierto rango, lo que de hecho puede evitar que ocurra la lectura fantasma. Sin embargo, esto no resuelve todos los problemas de concurrencia. Por ejemplo, los bloqueos de teclas no protegen contra los problemas de "sesgo de escritura", que pueden ocurrir cuando dos transacciones leen los mismos datos e intentan modificarlos.

Además, las cerraduras con llave adyacentes aumentan la sobrecarga de la cerradura, lo que posiblemente resulte en una reducción del rendimiento. Los bloqueos de teclas adyacentes deben bloquear un rango de registros, no solo un único registro, lo que puede evitar que otras transacciones simultáneas accedan al rango de registros, incluso si esas transacciones no entran en conflicto directamente con el registro bloqueado.

Por lo tanto, aunque el bloqueo de teclas puede resolver eficazmente el problema de la lectura fantasma, si puede llamarse "perfecto" debe tenerse en cuenta su posible impacto en la concurrencia y el rendimiento.

¿La lectura repetible está garantizada por bloqueos de fila?

Las garantías de lectura repetible (RR) no se basan únicamente en bloqueos de fila. En un sistema de base de datos real, el nivel de aislamiento de RR generalmente debe implementarse mediante la combinación de múltiples tecnologías, incluidos bloqueos de fila, bloqueos de brecha (Bloqueo de brecha), control de concurrencia de múltiples versiones (MVCC, Control de concurrencia de múltiples versiones), etc.

Los bloqueos de fila pueden evitar que la misma fila de datos sea modificada simultáneamente por otras transacciones, pero los bloqueos de fila no pueden evitar problemas de "lectura fantasma" (Phantom Read). La lectura fantasma significa que dentro de una transacción, los resultados de dos consultas son inconsistentes, y esta inconsistencia no se debe a la modificación de los registros consultados en sí, sino a la inserción de nuevos registros o la eliminación de registros antiguos.

Para resolver el problema de la lectura fantasma, muchos sistemas de bases de datos utilizan bloqueos de brecha (Gap Lock). Los bloqueos de brecha pueden bloquear la "brecha" entre dos registros de índice, evitando que otras transacciones inserten nuevos registros en esta brecha.

El control de concurrencia de múltiples versiones (MVCC) es otra tecnología importante, que permite que múltiples transacciones de lectura accedan a la misma fila de datos al mismo tiempo sin bloquearse entre sí. En MVCC, cada operación de escritura crea una nueva versión de la fila de datos y las operaciones de lectura acceden a una versión anterior adecuada. De esta forma, cada transacción puede ejecutarse en una instantánea coherente como si fuera la única en ejecución.

Por lo tanto, el nivel de aislamiento de lectura repetible generalmente requiere la implementación conjunta de múltiples tecnologías, como bloqueos de fila, bloqueos de espacio y MVCC.

Una pregunta del enlace MVCC

Texto original: MVCC guarda la versión histórica de los datos y decide si mostrar los datos de acuerdo con el número de versión de los datos comparados. Puede lograr el efecto de aislamiento de la transacción sin agregar un bloqueo de lectura y, finalmente, puede leer los datos en Al mismo tiempo Modificar, los datos se pueden leer al mismo tiempo que se modifican, lo que mejora en gran medida el rendimiento de concurrencia de las transacciones.

Pregunta: Cuando los datos se leen al escribir y se modifican al leer, ¿no habrá problemas de concurrencia?, por ejemplo, entran dos solicitudes al mismo tiempo, una lee y la otra escribe, pero primero se ejecuta la escritura y la lectura se ejecuta después de la operación de lectura. ¿Debería realizarse la operación en la versión actual de los datos o después de que se complete la operación de escritura?

Respuesta: Su comprensión del control de concurrencia de múltiples versiones (MVCC, control de concurrencia de múltiples versiones) es correcta. MVCC guarda la versión histórica de los datos y selecciona la versión adecuada al leer los datos, de modo que la operación de lectura y la operación de modificación se puedan realizar al mismo tiempo, mejorando así el rendimiento de concurrencia de la transacción.

Con respecto a la pregunta que mencionó, "¿Se leerán los datos cuando se escriban y se modificarán cuando se lean, no habrá problemas de concurrencia?" De hecho, existen reglas y estrategias correspondientes en el modelo MVCC para hacer frente a esta situación.

En MVCC, cada transacción obtiene un ID de transacción único (también conocido como número de versión) al principio. Cuando una transacción quiere leer un elemento de datos, ve la última versión con un número de versión no mayor que su propia ID de transacción. Cuando una transacción desea modificar un elemento de datos, crea una nueva versión cuyo número de versión es el ID de transacción de la transacción.

Entonces, para su pregunta, suponga que hay dos transacciones T1 (escritura) y T2 (lectura), donde la ID de transacción de T1 es más pequeña que la ID de transacción de T2. Si T1 se ejecuta primero, creará una nueva versión de datos, el número de versión es el ID de transacción de T1; luego, cuando T2 se ejecuta, verá la última versión cuyo número de versión no es mayor que el ID de transacción de T2, que es creado por T1 esa versión.

De esta forma, incluso si la operación de lectura y la operación de modificación se realizan simultáneamente, no habrá problemas de coherencia de datos, porque cada transacción se ejecuta en una instantánea de datos coherente. En este modo, las operaciones de lectura no bloquearán las operaciones de escritura y las operaciones de escritura no bloquearán las operaciones de lectura, logrando así un alto rendimiento de simultaneidad.

Tenga en cuenta, sin embargo, que si bien MVCC puede mejorar el rendimiento de la simultaneidad, no puede resolver todos los problemas de simultaneidad. Por ejemplo, no resuelve el problema de dos transacciones que modifican el mismo elemento de datos al mismo tiempo. Esta situación generalmente requiere el uso de bloqueos u otros mecanismos de control de concurrencia para su manejo.

¿La transacción T1 realiza cambios en los datos de la versión que contiene? En este caso, ¿es posible que se hayan modificado los datos leídos por T2?

En el mecanismo MVCC (Multi-Version Concurrency Control), cuando una transacción realiza una operación de escritura (como actualizar un elemento de datos), se creará una nueva versión del elemento de datos (de hecho, la nueva versión todavía se coloca en el fila de datos, la versión original se encuentra en la línea de registro de deshacer , consulte la demostración de mvcc link 2.4), en lugar de modificar directamente los datos originales. El número de versión de la nueva versión es igual al ID de transacción de la transacción. Se conserva una versión de los datos originales para que otras transacciones que todavía usan la versión anterior de los datos puedan continuar accediendo a ellos.

Supongamos que hay dos transacciones T1 y T2, T1 es una transacción de escritura, T2 es una transacción de lectura, sus ID de transacción son ID1 e ID2 e ID1 <ID2. Cuando T1 desea modificar un elemento de datos, crea una nueva versión de los datos con el número de versión ID1. Cuando T2 quiera leer este elemento de datos, verá la última versión cuyo número de versión no sea mayor que ID2. Debido a que ID1 <ID2, T2 puede ver la nueva versión creada por T1.

Sin embargo, qué versión de datos puede ver T2 depende de la hora de inicio de T1 y T2 y de la estrategia de implementación de MVCC. Por ejemplo, si T1 no se ha enviado cuando se inicia T2, entonces T2 solo puede ver la versión de datos antes de la modificación de T1; si T1 se ha comprometido cuando se inicia T2, entonces T2 puede ver la versión de datos después de la modificación de T1.

Cabe señalar que lo que MVCC puede asegurar es la vista consistente de la transacción, es decir, en una transacción, independientemente de si los datos son modificados por otras transacciones, los datos que ve siempre son consistentes. Para operaciones simultáneas de lectura y escritura, si habrá conflictos depende de la estrategia de control de simultaneidad específica y el nivel de aislamiento. En algunos casos, puede ser necesario utilizar bloqueos u otros mecanismos de sincronización para evitar conflictos de simultaneidad.

Cómo entender "Lo que MVCC puede garantizar es una vista consistente de las transacciones, es decir, en una transacción, independientemente de si los datos son modificados por otras transacciones, los datos que ve siempre son consistentes"

"Lo que MVCC puede garantizar es una vista consistente de las transacciones, es decir, en una transacción, independientemente de si los datos son modificados por otras transacciones, los datos que ve siempre son consistentes". el mecanismo (MVCC), cada transacción ve una instantánea de datos consistente y sin cambios, que depende del momento en que comienza la transacción. Esta es la llamada "visión de consistencia".

¿Cómo es esto posible? Cuando se inicia una transacción, obtiene un ID de transacción único, que también representa el momento en el que se inició la transacción. Cuando la transacción quiera leer un elemento de datos, verá la última versión con un número de versión no mayor que su propia ID de transacción. Es decir, la transacción solo puede ver la versión de los datos que existían cuando comenzó, no las nuevas versiones creadas por otras transacciones después de que comenzó. Incluso si otras transacciones modifican los datos durante la ejecución de la transacción, los datos vistos por esta transacción no cambiarán.

Por ejemplo, suponga que la transacción T1 comienza en el punto de tiempo 1 y la versión del elemento de datos A que lee en este momento es 1. Durante la ejecución de T1, otra transacción T2 modifica el elemento de datos A en el punto de tiempo 2, creando la versión 2. Sin embargo, aunque la versión real del elemento de datos A haya cambiado a 2, T1 todavía ve la versión 1 de los datos, porque la versión 1 es la versión que existía cuando se inició T1. Por lo tanto, no importa cómo cambien los datos, los datos vistos por T1 siempre son consistentes.

Esta característica hace posible que las operaciones de lectura no bloqueen las operaciones de escritura y que las operaciones de escritura bloqueen las operaciones de lectura bajo el mecanismo MVCC, lo que puede mejorar el rendimiento de la concurrencia. Al mismo tiempo, dado que cada transacción se ejecuta en una instantánea de datos coherente, también se puede garantizar la coherencia de la transacción.

Bajo el uso normal del mecanismo de bloqueo, la operación de escritura T1 y la operación de lectura T2, si T1 se ejecuta primero, entonces T2 solo puede bloquear y esperar a que se lean los datos actualizados después de que se ejecute T1.

En el caso de utilizar el mecanismo de bloqueo, si una transacción (T1) adquiere un bloqueo de escritura en un elemento de datos, todas las demás transacciones (como T2) que intenten leer o escribir este elemento de datos se bloquearán hasta que T1 libere el bloqueo. . Por lo tanto, en este caso, T2 esperará a que T1 termine de ejecutarse y libere el bloqueo antes de leer los datos actualizados.

Esta situación de bloqueo de espera puede provocar una disminución del rendimiento de la concurrencia, especialmente en un sistema de alta concurrencia. Para resolver este problema, una forma es utilizar un mecanismo de control de concurrencia sin bloqueo, como MVCC (Control de concurrencia de múltiples versiones). En MVCC, las operaciones de lectura no bloquean las operaciones de escritura y las operaciones de escritura no bloquean las operaciones de lectura, lo que mejora el rendimiento de la simultaneidad.

Sin embargo, aunque MVCC puede mejorar el rendimiento de la simultaneidad, también tiene algunas limitaciones y sobrecarga, como la necesidad de mantener varias versiones de datos y la necesidad de lidiar con conflictos de versión. Por lo tanto, en aplicaciones prácticas, se debe seleccionar una estrategia de control de concurrencia adecuada de acuerdo con las necesidades y entornos específicos.

Si la transacción se ejecuta en medio de la operación de escritura T1, pero T2 lee los datos nuevamente después del final de T1, ¿se leen los datos en este momento después del envío o antes del envío?

En el modelo de control de simultaneidad de múltiples versiones (MVCC), se obtiene un ID de transacción cuando se inicia una transacción, que también es una marca de tiempo, que representa el momento en que se inicia la transacción. Todas las operaciones de lectura de datos de esta transacción solo verán la versión de los datos antes de su hora de inicio (es decir, el ID de la transacción).

Si la transacción de escritura T1 se compromete durante la ejecución, su modificación de los datos generará una nueva versión de los datos. El número de versión de esta nueva versión será igual al ID de transacción de T1.

Para la transacción de lectura T2, si comenzó antes de que T1 se confirme, incluso si T1 envía una nueva versión de datos, T2 solo puede ver la versión de datos en el momento en que comenzó, es decir, ve que todavía son los datos antes del envío de T1.

Sin embargo, si T2 comienza después de que T1 se confirma, entonces cuando T2 lea los datos, verá la nueva versión de los datos enviados por T1, porque esta versión de los datos ya existía antes de que T2 comenzara.

Por lo tanto, si T2 lee los datos después del envío o los datos antes del envío depende de si la hora de inicio de T2 es antes o después del envío de T1. Así es como el modelo MVCC puede proporcionar una vista consistente.

Pregunta sobre la vista de lectura

Material:

2.5 Condiciones de coincidencia de vista de lectura:

1. Si se muestra el ID de transacción de datos <up_limit_id

Si la ID de la transacción de datos es menor que la ID de transacción activa mínima en la vista de lectura, es seguro que los datos ya existían antes de que se iniciara la transacción actual, por lo que se pueden mostrar.

2. No se mostrará ID de transacción de datos>=low_limit_id

Si el ID de transacción de datos es mayor que el ID de transacción máximo del sistema actual en la vista de lectura, significa que los datos se
generan después de crear la vista de lectura actual, por lo que los datos no se mostrarán.

3. Up_limit_id <= ID de transacción de datos < low_limit_id coincidirá con el conjunto de transacciones activas trx_ids

Si la ID de transacción de los datos es mayor que la ID de transacción activa más pequeña y menor o igual que la ID de transacción más grande del sistema, esta situación indica que es posible que los datos no se hayan enviado cuando comenzó la transacción actual.

Entonces, en este momento, debemos hacer coincidir el ID de transacción de los datos con el conjunto de transacciones activas trx_ids en la vista de lectura actual:

Caso 1: si el ID de transacción no existe en la colección trx_ids (significa que la transacción se ha confirmado cuando se genera la vista de lectura), se pueden mostrar los datos en este caso.


Caso 2: si el ID de transacción existe en trx_ids, significa que los datos no se han enviado cuando se genera la vista de lectura , pero si el ID de transacción de los datos es igual a author_trx_id
, significa que los datos son generados por el la transacción actual en sí, y los datos generados por sí mismos se pueden ver por sí mismos, por lo que en este caso los datos también se pueden mostrar.

Caso 3: si el ID de la transacción existe en trx_ids y no es igual a created_trx_id, significa que
los datos no se han enviado cuando se genera la vista de lectura y no se generan por sí mismos, por lo que los datos no se pueden mostrar en este caso. .

4. Cuando no se cumple la condición de vista de lectura, los datos se obtienen del registro de deshacer

Cuando el ID de transacción de los datos no cumple con la condición de vista de lectura, la versión histórica de los datos se obtiene del registro de deshacer, y luego el número de transacción de la versión histórica de los datos se compara con la condición de vista de lectura hasta que se obtiene una parte
. de datos históricos que cumplen la condición se encuentra, o si no se encuentra, devuelve un resultado vacío;

¿Cómo entiende que el "ID de transacción de datos" aquí se refiere al ID de transacción de lectura actual? ¿Por qué el número de transacción no es el más grande? ¿No debería aumentar automáticamente el ID de transacción?

En el motor InnoDB de MySQL, las transacciones utilizan el mecanismo de control de concurrencia de múltiples versiones (MVCC). Bajo este mecanismo, cada fila de datos tiene un ID de transacción asociado, que representa al creador de esta versión de la fila de datos. Cuando una transacción modifica una fila de datos, crea una nueva versión de la fila de datos y el ID de transacción de la nueva versión es el ID de la transacción. Por lo tanto, "ID de transacción de datos" se refiere al ID de transacción que creó esta versión de fila de datos.

Para su primera pregunta, el "ID de transacción de datos" no es el ID de la transacción de lectura actual, sino el ID de la transacción que creó la versión actual de la fila de datos. El motor InnoDB utiliza una ID de transacción de incremento automático para identificar transacciones, pero lo que debe comprender es que la ID obtenida por cada transacción al principio es el valor máximo en ese momento, y la ID obtenida por el la transacción que comienza más tarde será más grande. Por lo tanto, si la ID de transacción de una fila de datos (es decir, la ID de la transacción que la creó) es menor que la ID de transacción activa mínima en la vista de lectura, entonces podemos estar seguros de que esta fila de datos se creó antes de la comienza la transacción actual, por lo que puede ser visto por la transacción actual.

¿Los "datos" aquí se refieren a la última versión actual del registro que se almacena en la tabla?

Para su segunda pregunta, "los datos" se refiere a alguna versión de la fila de datos a la que intenta acceder la transacción de lectura actual. Es posible que esta versión no sea la última versión de la fila de datos, porque en MVCC, la transacción de lectura puede ver la versión anterior de la fila de datos, según la hora de inicio de la transacción de lectura y el contenido de la vista de lectura. Así es como MVCC puede proporcionar una vista consistente.

En el siguiente caso, es posible que el ID de la transacción de datos sea una operación de escritura que se haya ejecutado antes de tiempo, ¿verdad?

ID de transacción de datos>=low_limit_id no se mostrará

Si el ID de transacción de datos es mayor que el ID de transacción máximo del sistema actual en la vista de lectura, significa que los datos se
generan después de crear la vista de lectura actual, por lo que los datos no se mostrarán.

En el caso que mencionó, la "ID de transacción de datos" puede haber sido creada por una transacción de escritura confirmada. Si el ID de transacción de la fila de datos es mayor que low_limit_id de la vista de lectura, significa que la versión de la fila de datos se creó después de que comenzara la transacción de lectura actual. Por lo tanto, incluso si se ha confirmado la transacción de escritura, la transacción de lectura actual aún no verá esta versión de datos, porque en MVCC, cada transacción solo puede ver la versión de datos en y antes de su hora de inicio.

En este momento, la lista de transacciones activas en la vista de lectura son todas las transacciones de lectura. ¿Hay transacciones de escritura?

La lista de transacciones activas registradas en la vista de lectura incluye todas las transacciones no confirmadas al comienzo de la transacción de lectura, sin importar si estas transacciones son transacciones de lectura o escritura. Si es una transacción de escritura, puede modificar los datos más tarde, creando una nueva versión de los datos, pero estas nuevas versiones de los datos no serán vistas por la transacción de lectura actual. Si es una transacción de lectura, no modificará los datos, pero para evitar problemas de lectura fantasma (phantom read), debe incluirse en la lista de transacciones activas.

¿Por qué se puede evitar el problema de la lectura fantasma colocando la transacción de lectura en la lista de transacciones activas de la vista de lectura?

La lectura fantasma es un problema de control de concurrencia. Cuando una transacción lee algunas filas, otra transacción inserta algunas filas nuevas y luego vuelve a leer, la transacción original encuentra que aparecen nuevas filas "fantasmas". Si la transacción de lectura se coloca en la lista de transacciones activas de la vista de lectura, otras transacciones de lectura simultáneas no pueden ver los cambios no confirmados de la transacción de escritura, por lo que no verá nuevas filas "fantasmas" en la vista de consistencia, evitando así la lectura fantasma. problema. Esto está determinado por la especificación mvcc: una transacción solo puede ver los datos de la versión cuyo número de versión es menor o igual que la identificación de la transacción actual

¿Por qué la identificación de la transacción de la fila actualizada aún puede existir en la lista de transacciones activas? Dado que la fila se ha actualizado, ¿no debería significar que se ha enviado?

En primer lugar, la "fila actualizada" aquí solo significa que la versión anterior de los datos se ha movido al registro de deshacer, y la nueva versión de los datos ocupa la fila de datos actual. Parece estar actualizado, pero no lo ha sido. enviado todavía, por lo que la vista de lectura en sí también puede estar en la lista de transacciones activas.

Desventajas de MVCC relacionadas

¿Qué es el sesgo de escritura?

El sesgo de escritura es un fenómeno más complejo (el problema de las escrituras simultáneas), que implica que dos o más transacciones lean los mismos datos al mismo tiempo y luego los modifiquen en función de la lectura de datos. Esto puede dejar la base de datos en un estado inconsistente. Por ejemplo, dos transacciones leen los mismos datos y luego los modifican en función de los datos leídos, lo que puede causar algunos conflictos e incoherencias en los datos. Para resolver el sesgo de escritura, puede ser necesario adoptar un mecanismo de control de concurrencia más avanzado, como el bloqueo optimista (Bloqueo optimista) o el bloqueo pesimista (Bloqueo pesimista)

Por ejemplo:
si hay dos asientos y dos usuarios (transacción A y transacción B) reservan cada uno un asiento, entonces el número de asientos debe convertirse en 0, cuando A y B lean simultáneamente los asientos restantes (2), entonces todo fue decidieron reservar un asiento, cada uno pensando que debería quedar un asiento después de la reserva. Pero cuando se envían ambas transacciones, dado que ambas restan un asiento de 2, el resultado será 1 asiento en lugar de 0. Este es el llamado problema de sesgo de escritura.

¿Qué pasa con la lectura sesgada?

Read Skew (leer sesgado): en la misma transacción, leer el mismo elemento de datos varias veces arroja resultados diferentes. Este es el problema de "lectura no repetible" mencionado anteriormente en Read-Write Skew.

¿Cuáles son los defectos de MVCC?

MVCC no puede resolver el problema de simultaneidad de múltiples transacciones de escritura (no puede resolver el problema de desviación de escritura) y solo puede usarse para resolver el problema de simultaneidad entre transacciones de lectura y escritura.

¿Por qué mvcc no puede resolver el problema de concurrencia entre múltiples transacciones compuestas de lectura y escritura o entre transacciones de escritura y escritura?

Tipo de transacción

Transacciones compuestas de solo lectura, solo escritura, lectura-escritura, generalmente mvcc solo puede resolver transacciones de solo lectura y solo escritura, o problemas de concurrencia entre transacciones de solo lectura y solo lectura, pero no puede resolver transacciones compuestas o entre escritura- transacciones de solo y solo escritura Problemas de simultaneidad entre

Para transacciones que incluyen operaciones de lectura y escritura, MVCC también puede manejar bien las operaciones de lectura. Sin embargo, para las operaciones de escritura, si la operación de escritura depende de la operación de lectura en la transacción, entonces puede haber problemas. Este es el llamado "sesgo de lectura-escritura" (sesgo de lectura-escritura)

¿Cómo resolver el problema de sesgo de escritura de mvcc o el problema de transacción de escritura-escritura?

1 Permite que la transacción se ejecute en serie (nivel de aislamiento serializado), pero la concurrencia es muy baja
2 El bloqueo optimista con número de versión se usa en la base de datos, de modo que solo se ejecutará una transacción con éxito cada vez
3 Los bloqueos distribuidos se pueden usar para Permitir Solo se libera una transacción cada vez que se modifica la fila de datos o el negocio relacionado en la base de datos.4
Bloqueo pesimista: el bloqueo pesimista asume que las transacciones simultáneas causarán inconsistencias en los datos, por lo tanto, bloquee antes de modificar los datos para evitar modificaciones simultáneas por parte de otras transacciones. En nuestro ejemplo de cuenta bancaria, la cuenta podría estar bloqueada entre verificar el saldo y cambiar el saldo. De esta manera, solo cuando se completa una transacción, otra transacción puede continuar, evitando así el problema del sesgo de escritura. Sin embargo, el bloqueo pesimista puede provocar un rendimiento de simultaneidad degradado.

Escenarios de aplicación de MVCC

Mvcc, como otros bloqueos, solo puede garantizar el aislamiento de las transacciones y no puede garantizar la seguridad de las transacciones que dependen del negocio, ¿verdad?

Sí, MVCC solo puede garantizar el aislamiento de las transacciones, es decir, las transacciones ejecutadas al mismo tiempo no interferirán entre sí. Sin embargo, no garantiza operativamente las dependencias existentes. Esto debe manejarse en el nivel de lógica empresarial. Por ejemplo, en el escenario de venta relámpago, incluso si se utiliza MVCC, es posible que sea necesario utilizar técnicas como el bloqueo optimista o el bloqueo pesimista para garantizar que el producto no se sobrevenda.

Lectura instantánea y lectura actual, cuál debe usarse en el escenario seckill

En el escenario seckill, generalmente necesitamos asegurar la corrección del inventario, por lo que necesitamos conocer el estado actual del inventario en tiempo real, es decir, necesitamos "lectura actual". Aunque la lectura de instantáneas puede proporcionar un alto rendimiento de simultaneidad, debido a que se basa en una instantánea de datos en un momento determinado, es posible que no refleje el estado del inventario en tiempo real, por lo que puede no ser adecuada para escenarios que requieren un alto rendimiento en tiempo real. como seckill.

La instantánea puede leer datos antiguos. ¿Hay algún problema de seguridad?

Los datos leídos por la instantánea pueden ser antiguos, lo que puede causar problemas en algunos escenarios. Tomando Lightning Deal como ejemplo, si realizamos un pedido en función de los datos de inventario leídos en la instantánea, es posible que se sobrevenda. Por ejemplo, el inventario real de un producto es solo 1, pero en las lecturas instantáneas de varias transacciones, todos ven que el inventario es 1, por lo que todos hacen un pedido y, como resultado, se venden realmente varios productos. es una especie de pregunta de seguridad.

Sin embargo, esto no quiere decir que las lecturas de instantáneas no sean útiles. En algunos escenarios que no tienen requisitos altos para datos en tiempo real pero tienen requisitos altos para el rendimiento de simultaneidad, la lectura de instantáneas puede proporcionar un mejor rendimiento. Por ejemplo, si queremos contar el historial de compras del usuario, en este caso, el rendimiento en tiempo real de los datos no es tan importante y la lectura de instantáneas puede proporcionar un mejor rendimiento de concurrencia.

Con respecto a si usar la lectura instantánea o la lectura actual, ¿se puede configurar la base de datos mysql y la granularidad es precisa para la tabla o la biblioteca?

En MySQL, puede elegir usar lecturas instantáneas (también conocidas como lecturas consistentes) o lecturas actuales por transacción. Esto se logra estableciendo el nivel de aislamiento de la transacción. Por ejemplo, si elige el nivel de aislamiento "LECTURA COMPROMETIDA", cada consulta leerá los datos más recientes (lectura actual). Y si selecciona el nivel de aislamiento "LECTURA REPETIBLE", se creará una instantánea de datos al comienzo de la transacción, y todas las consultas posteriores leerán datos basados ​​en esta instantánea (lectura de instantánea). Esta configuración es por transacción, no específica para tablas o bibliotecas.

Supongo que te gusta

Origin blog.csdn.net/yxg520s/article/details/131817634
Recomendado
Clasificación