MVCC — Multiversion Concurrency Control
En la guía anterior vimos cómo los locks coordinan el acceso: quien no consigue permiso, espera. MVCC ataca el mismo problema con otra estrategia: en lugar de bloquear, mantiene múltiples versiones de cada fila.
Por qué una sola versión genera bloqueos
Sin MVCC, la estrategia más simple es bloquear la fila antes de leer o escribir:
| Operación | Estrategia | Consecuencia |
|---|---|---|
SELECT sobre una fila en modificación |
Bloquear la fila hasta que termine la escritura | Lectores esperan |
UPDATE sobre una fila siendo leída |
Bloquear la fila hasta que termine la lectura | Escritores esperan |
En un sistema con alta concurrencia, esto crea un cuello de botella. Cada transacción que toca una fila afecta a todas las demás que quieran acceder a ella.
MVCC reduce significativamente estos bloqueos, permitiendo que en muchos casos lecturas y escrituras ocurran simultáneamente.
Cómo funciona MVCC
Múltiples versiones en lugar de bloqueos
Cuando una transacción modifica una fila, la base de datos no sobrescribe el dato original. Crea una nueva versión y mantiene la anterior. La versión antigua sigue existiendo para que otras transacciones puedan leerla.
Qué versión ve cada transacción
Cuando una transacción lee, el sistema decide qué versiones son visibles mediante un snapshot: una foto del estado en el momento en que la transacción comenzó. Ve lo que estaba comprometido en ese instante y su propio trabajo; no ve lo que otros comprometan después.
Qué pasa con el espacio
MVCC no es gratis: cada modificación crea una nueva versión y las versiones antiguas se acumulan.
- Mientras una transacción esté activa, no puede eliminarse la versión que podría necesitar
- Como las versiones antiguas dejan de ser útiles con el tiempo, el sistema debe limpiarlas periódicamente con un mecanismo de recolección
MVCC y locks
MVCC reduce los bloqueos entre lecturas y escrituras, pero no los elimina por completo. Siguen existiendo situaciones donde intervienen locks:
- Escrituras concurrentes sobre la misma fila: El sistema necesita algún mecanismo de coordinación para evitar lost updates
- Operaciones DDL: Modificar la estructura de una tabla generalmente requiere bloqueo exclusivo
- Transacciones de larga duración: Pueden impedir la limpieza de versiones que otras transacciones necesitan
MVCC y niveles de aislamiento
Los niveles de aislamiento son estrategias que usan MVCC (u otros mecanismos) para definir qué tanto se aíslan las transacciones entre sí.
| Nivel | Qué hace con MVCC |
|---|---|
| Read Committed | Cada consulta puede ver versiones distintas según cuándo se ejecuta |
| Repeatable Read | Toda la transacción ve el mismo conjunto de versiones desde el inicio |
| Serializable | Va más allá de MVCC y agrega verificaciones adicionales |
No todos los motores usan MVCC de la misma forma. Algunos lo combinan con bloqueos, otros lo implementan de forma pura. El nivel de aislamiento que elijas determina cómo se comporta MVCC en la práctica.
Trade-offs
| Aspecto | MVCC | Bloqueo tradicional |
|---|---|---|
| Lecturas concurrentes | Sí Lecturas no esperan escrituras | No Lectores esperan escritores |
| Escrituras concurrentes | Ojo Coordinación necesaria misma fila | No Escritores bloquean lectores |
| Consistencia de lectura | Depende Del nivel de aislamiento (qué snapshot se usa) | Depende Del nivel de aislamiento |
| Uso de espacio | Más Múltiples versiones acumuladas | Menos Una sola versión por fila |
| Limpieza | Sí, exige Mecanismo necesario | No No requiere limpieza |
Errores frecuentes
Error: MVCC elimina completamente la necesidad de bloqueos.
No. MVCC resuelve el conflicto reader-writer, pero para escrituras concurrentes sobre la misma fila, la base de datos sigue necesitando algún mecanismo de coordinación. También pueden requerir bloqueos operaciones DDL o transacciones de larga duración que impiden la limpieza de versiones.
Error: Snapshot y MVCC son lo mismo.
MVCC es el mecanismo que mantiene múltiples versiones. El snapshot es una estrategia que muchos motores usan para determinar qué versiones son visibles. MVCC es el concepto general, el snapshot es una implementación posible.