Command Palette

Search for a command to run...

ES·EN

Nivel 2 · 25 min

MVCC

MVCC (Multi-Version Concurrency Control) es el mecanismo que permite a PostgreSQL ejecutar lecturas y escrituras simultáneamente sin bloquearse entre sí. Cada fila puede tener múltiples versiones; cada transacción ve una snapshot consistente del momento en que comenzó.

Aislamiento por Snapshot

Cuando una transacción comienza, recibe un snapshot del estado de la base de datos. Las lecturas posteriores ven las filas que estaban committed en ese momento —no ven cambios de transacciones que committearon después. Esto elimina la necesidad de locks de lectura: los writers no bloquean readers y viceversa.

xmin, xmax y Visibilidad

Cada fila tiene columnas de sistema xmin (ID de transacción que la insertó) y xmax (ID de transacción que la eliminó o actualizó). Para determinar si una fila es visible, PostgreSQL chequea si xmin está committed y es anterior al snapshot, y si xmax está vacío o es posterior al snapshot. UPDATE en realidad inserta una fila nueva y marca la vieja con xmax.

VACUUM y Dead Tuples

Las filas viejas (dead tuples) se acumulan porque no se eliminan inmediatamente. VACUUM las marca como reusables sin devolver espacio al OS. Autovacuum corre automáticamente pero puede ser insuficiente en tablas con alta tasa de UPDATE. El bloat excesivo ralentiza seq scans porque hay que leer más páginas para encontrar las filas vivas.

Puntos clave

  • MVCC permite lecturas no bloqueantes —readers y writers operan en paralelo usando versiones de fila.
  • UPDATE es insert + delete en MVCC, lo que significa que las tablas con muchos UPDATEs acumulan dead tuples rápidamente.
  • Autovacuum debe estar correctamente configurado para tablas de alta escritura; el default puede ser insuficiente.

Code example

-- Ver dead tuples por tabla
SELECT schemaname, relname,
       n_dead_tup, n_live_tup,
       last_autovacuum, last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;

-- Forzar VACUUM en tabla específica
VACUUM (VERBOSE, ANALYZE) orders;

-- Ver filas con xmin/xmax (columnas de sistema)
SELECT xmin, xmax, id, status FROM orders WHERE id = 42;