Introducción
Antes de explicar que es el proceso de vacuum y para que se utiliza, explicaremos unos conceptos básicos que nos ayudarán a comprender porqué existe este proceso.
PostgreSQL es una base de datos relacional que cumple con el conjunto de propiedades ACID (Atomicidad, Consistencia, Aislamiento y Durabilidad) para garantizar que las transacciones son procesadas de manera fiable. Para conseguir que se cumplan estas propiedades, PostgreSQL usa un mecanismo que se denomina Control de Concurrencia.
Existen diferentes técnicas para control de concurrencia, PostgreSQL implementa Multi Version Concurrency Control (MVCC) para proteger la consistencia del dato. Oracle, por ejemplo, usa los segmentos de rollback.
Con MVCC cuando se realiza una operación de borrado o actualización en la base de datos, los datos no son modificados dentro del mismo registro físico, sino que se crea una nueva versión del registro o de la tupla, manteniendo la versión antigua. Mediante la aplicación de reglas de verificación de visibilidad (Visibility Check Rules), se puede determinar si una tupla es visible o invisible.
Para identificar si una tupla es visible o no, cada vez que se inicia una transacción, el gestor de transacciones asigna un identificador único, denominado identificador de transacción (txid). En PostgreSQL, este identificador (número entero de 32 bit) puede identificar hasta 4,2 billones de transacciones. Sin embargo, PostgreSQL trata los txid de manera circular ( ver figura 1), lo que hace que solo la mitad de las transacciones (2,1 billones) son tratadas como visibles.
Esta forma de tratar los txid, tiene un problema que es conocido como wraparound, que lo comentaremos más adelante.
s
Figura 1. Modelo circular de transacciones
¿Por qué es necesario el proceso de vacuum, cuál es su funcionalidad?
Veamos un pequeño ejemplo que nos ayudará a comprender el porqué es necesario el proceso de vacuum.
Creamos una tabla e insertamos 100.000 registros. Podemos observar que el tamaño de la tabla es de 3576Kb. Inmediatamente después se realiza un update en la tabla sobre 50.000 registros. Sería de esperar que el tamaño de la tabla no aumentara, sin embargo se observa que la tabla ahora ocupa 5344Kb (aprox. 49% más).
¿Cómo es posible?. Recordar que PostgreSQL usa MVCC por lo que cuando se hace un update, internamente se comporta como si se hiciera un delete más insert.
Podemos pensar, bueno si borro todas las filas de la tabla se reducirá el espacio…
Upss! He borrado todos los registros de la tabla y sin embargo el tamaño de la tabla no se ha reducido, sigue ocupando 5344 Kb.
¿Qué es lo que está pasando? ¿ Y si ejecuto el proceso de vacuum…?
Observamos que ahora el tamaño de la tabla es de solo 16 Kb.¿¿??
Como hemos comentado anteriormente, por el funcionamiento intrínseco de PostgreSQL (MVCC). Cuando se realiza un borrado o una actualización de una tupla, estas no son eliminadas físicamente de su tabla, sino que persisten dentro del servidor y se marcan como tuplas muertas.
Básicamente el proceso de vacuum se utiliza para realizar aquellas tareas de mantenimiento y limpieza sobre los datos de las tablas e índices que han sido modificados. Principalmente sirve para dos propósitos:
- Reclamar espacio ocupado por las tuplas muertas.
- Recolectar información para el optimizador.
¿Por qué es importante el vacuum y autovacuum en una base de datos?
Este es uno de los procesos de mantenimiento más importantes a considerar dentro de la gestión de una base de datos PostgreSQL. Aunque este proceso no es obligatorio dentro de una base de datos, es altamente recomendable que esté activo. Sobre todo en bases de datos productivas con una alta transaccionalidad. Imaginemos una base de datos que actualiza e inserta millones de registros al día. Si no existiera este proceso llegaría un momento en que las tablas crecerían sin control, el registro de transacciones se quedaría sin identificadores de transacción, se producirían problemas de rendimiento, almacenamiento, etc. En resumen, no funcionará como se espera en un sistema RDBMS, por lo que el proceso esté siempre activo, tiene unas grandes ventajas pero también ciertos inconvenientes.
Ventajas
- Nos permite automatizar las tareas de vacuum y analyze de las bases de datos.
- Nos ayuda a prevenir problemas de wraparound.
- Previene un crecimiento excesivo de las tablas e índices (bloat).
- Se pueden configurar parámetros que gobiernan la ejecución del proceso de vacuum o autovacuum.
- Se pueden crear múltiples procesos (llamados workers) para mejorar y/o paralelizar la ejecución de las tareas de vacuum.
Inconvenientes
- Los procesos de vacuum tienen gran coste en referencia a operaciones de I/O en disco.
- Los procesos de autovacuum no pueden procesar las tablas temporales. Tiene que realizarse manualmente.
- Los procesos de autovacuum no soportan procesos paralelos.
- Tareas muy agresivas de vacuum pueden afectar al rendimiento general de la base de datos.
- El vacuum full necesita un bloqueo exclusivo sobre el objeto.