Limpieza de versiones antiguas con VACUUM en Delta Lake y Microsoft Fabric
En cualquier arquitectura de datos moderna basada en Lakehouse, la inmutabilidad es una pieza fundamental. Delta Lake, el estándar de almacenamiento en Microsoft Fabric, gestiona las actualizaciones y eliminaciones mediante un registro de transacciones (Delta Log) y la creación de nuevos archivos Parquet, en lugar de modificar los existentes. Este enfoque garantiza la atomicidad y permite funciones críticas como el Time Travel, pero tiene un efecto secundario inevitable: el crecimiento exponencial del almacenamiento si no se gestiona correctamente.
Como consultores, a menudo encontramos entornos donde el rendimiento de las consultas es aceptable, pero la factura de almacenamiento en OneLake se dispara sin una justificación clara en el volumen de datos de negocio. El culpable suele ser la acumulación de archivos obsoletos que ya no forman parte del estado actual de las tablas, pero que permanecen en el disco para permitir viajes en el tiempo a versiones pasadas. Aquí es donde entra en juego la sentencia VACUUM.
El comando VACUUM no es una sugerencia de optimización, sino una tarea de mantenimiento obligatoria en cualquier ciclo de vida de ingeniería de datos. Su función es identificar y eliminar físicamente los archivos de datos que ya no están referenciados por el registro de transacciones de Delta y que han superado un umbral de retención determinado. En este artículo analizaremos cómo implementar esta limpieza, los riesgos asociados y cómo integrarla en tus flujos de trabajo en Microsoft Fabric.
El mecanismo de persistencia y el coste del Time Travel
Para entender por qué necesitamos VACUUM, debemos comprender cómo escribe Spark en una tabla Delta. Cuando realizas un UPDATE sobre una tabla de FactVentas para corregir el Importe de una transacción, Delta Lake no busca el archivo Parquet original para sobrescribir la línea. En su lugar, marca el archivo antiguo como eliminado en el log de transacciones y escribe un nuevo archivo con el dato corregido.
Este diseño permite que, si un analista necesita auditar el estado de las ventas tal como estaban hace tres días, pueda ejecutar una consulta de Time Travel. Sin embargo, esto significa que ambos archivos (el antiguo y el nuevo) coexisten en OneLake. En entornos con cargas incrementales frecuentes o procesos de limpieza de datos constantes, el número de archivos «fantasma» puede triplicar o cuadruplicar el tamaño real de la tabla. Si quieres profundizar en cómo se gestionan estos metadatos, te recomiendo revisar nuestro artículo sobre Checkpoints de Delta en Fabric: Optimización de metadatos y velocidad de lectura.
Implementación técnica de VACUUM en Spark
La ejecución de VACUUM se realiza habitualmente a través de Notebooks en Microsoft Fabric utilizando PySpark o Spark SQL. Por defecto, Delta Lake establece un umbral de retención de 168 horas (7 días). Esto significa que cualquier archivo que haya dejado de ser necesario hace menos de una semana no será eliminado, protegiendo así la capacidad de realizar Time Travel reciente.
Es fundamental realizar una prueba antes de ejecutar el borrado físico. El parámetro DRY RUN nos permite previsualizar qué archivos serían eliminados sin llegar a ejecutar la acción. Es una práctica de seguridad básica que todo ingeniero debería aplicar antes de comprometer cambios en producción.
# Ejemplo de inspección previa (Dry Run) para la tabla de Ventas
tabla_ventas = "Ventas_Retail"
# Ejecutamos VACUUM en modo prueba para ver qué archivos se borrarían
# con el periodo de retención por defecto (7 días)
spark.sql(f"VACUUM {tabla_ventas} RETAIN 168 HOURS DRY RUN").show(truncate=False)
# Si el resultado es el esperado, ejecutamos la limpieza real
# spark.sql(f"VACUUM {tabla_ventas} RETAIN 168 HOURS")Si intentas reducir este periodo por debajo de las 168 horas, Spark lanzará una excepción de seguridad. Esto se debe a que reducir agresivamente la ventana de retención puede causar problemas si hay procesos de lectura largos o si se necesita recuperar datos tras un error humano. Para forzar una retención menor, es necesario modificar la configuración de la sesión, algo que solo recomendamos en entornos de desarrollo o tablas temporales con una rotación muy alta.
Comparativa: VACUUM vs OPTIMIZE
Es común confundir VACUUM con OPTIMIZE. Aunque ambos forman parte del mantenimiento de tablas Delta, atacan problemas distintos. Mientras que el primero se centra en el espacio físico y la eliminación de residuos, el segundo se enfoca en la eficiencia de lectura mediante la compactación de archivos pequeños (el famoso problema de los «small files»).
| Característica | OPTIMIZE | VACUUM |
|---|---|---|
| Objetivo principal | Rendimiento de lectura (compactación) | Recuperación de espacio (limpieza) |
| Archivos afectados | Agrupa archivos pequeños en otros más grandes | Elimina archivos no referenciados por el log |
| Impacto en Time Travel | No afecta a la capacidad de volver atrás | Elimina la posibilidad de volver a versiones anteriores a la retención |
| Frecuencia recomendada | Después de cada carga importante | Semanal o mensual (según volumen) |
| Coste de ejecución | Alto (consume mucho cómputo Spark) | Bajo (principalmente operaciones de listado y borrado) |
En proyectos de gran escala, como los que tratamos en nuestra Guía técnica de optimización de costes en OneLake, la combinación de ambas tareas es lo que mantiene la capacidad de Fabric dentro de límites razonables de gasto.
Configuración avanzada y gestión de riesgos
Existen escenarios donde la retención de 7 días es excesiva. Por ejemplo, en tablas de staging que se vacían y recargan cada pocas horas. Para estos casos, podemos desactivar la comprobación de seguridad de retención, aunque debe hacerse con extrema cautela.
# Desactivar la validación de duración mínima de retención
spark.conf.set("spark.databricks.delta.retentionDurationCheck.enabled", "false")
# Limpiar una tabla de Staging dejando solo las últimas 24 horas
spark.sql("VACUUM Staging_Pedidos RETAIN 24 HOURS")
# Es una buena práctica volver a activar la protección inmediatamente después
spark.conf.set("spark.databricks.delta.retentionDurationCheck.enabled", "true")Riesgos de una limpieza agresiva
El mayor riesgo de ejecutar VACUUM con una retención muy corta es la inconsistencia en las lecturas activas. Si un usuario está ejecutando una consulta larga que comenzó antes de la limpieza, y el comando VACUUM elimina un archivo que esa consulta todavía necesita leer, la consulta fallará con un error de «File not found».
Además, una vez que VACUUM borra los archivos, la operación es irreversible. No hay papelera de reciclaje en OneLake para estos objetos. Si no tienes un backup externo o una estrategia de recuperación de desastres, perderás la capacidad de auditar cambios históricos más allá del umbral definido.
Integración en el ciclo de vida del dato en Fabric
No deberías ejecutar VACUUM de forma manual cada vez que te acuerdes. En Microsoft Fabric, la mejor estrategia es automatizar estas tareas mediante Pipelines o Notebooks programados. Un patrón habitual es dedicar una ventana de mantenimiento semanal, preferiblemente en horas de baja actividad, para procesar todas las tablas del Lakehouse.
Considera también el uso de Shortcuts en OneLake. Si tu tabla Delta apunta a datos mediante shortcuts a un Azure Data Lake Gen2 o S3, VACUUM también eliminará los archivos en el destino remoto si el shortcut tiene permisos de escritura. Esto es potente pero peligroso si el almacenamiento externo es compartido por otros sistemas.
Por otro lado, la seguridad sigue siendo primordial. Antes de automatizar procesos que borran datos, asegúrate de que las identidades que ejecutan los Notebooks tienen los permisos adecuados, aplicando principios de seguridad RLS y CLS en Fabric para limitar quién puede disparar estas acciones de mantenimiento.
Errores comunes en el uso de VACUUM
- Ejecutar VACUUM sin OPTIMIZE: Si solo limpias pero no compactas, seguirás teniendo un rendimiento pobre debido a la fragmentación del almacenamiento.
- Retención cero en producción: Establecer
RETAIN 0 HOURSes una receta para el desastre. Cualquier fallo en una carga concurrente o una lectura prolongada romperá el sistema. - Ignorar el log de transacciones:
VACUUMno limpia el_delta_log. Para limpiar los archivos JSON de metadatos antiguos, debes configurar la propiedaddelta.logRetentionDurationen la tabla. - No monitorizar el espacio recuperado: Es vital medir cuánto espacio estamos liberando para justificar el uso de recursos de computación (unidades de capacidad de Fabric) para estas tareas.
Para una gestión integral del linaje y saber qué tablas están creciendo de forma anómala, la integración de Microsoft Purview con Fabric puede darte la visibilidad necesaria para priorizar qué tablas necesitan un VACUUM urgente.
Checklist de mantenimiento para tablas Delta
- Identificar tablas críticas: Localiza las tablas con mayor tasa de actualización (volatilidad).
- Validar el periodo de retención: Confirma con el negocio cuántos días de Time Travel son realmente necesarios por cumplimiento o auditoría.
- Ejecutar Dry Run: Verifica siempre el impacto antes de realizar el borrado físico.
- Programar en horas valle: Evita conflictos con procesos de ingesta pesados o usuarios finales consultando informes de Power BI.
- Monitorizar costes: Comprueba la métrica de almacenamiento en el portal de administración de Fabric tras las limpiezas periódicas.
Preguntas frecuentes
¿VACUUM afecta al rendimiento de mis informes de Power BI?
Indirectamente sí, de forma positiva. Al eliminar archivos innecesarios, las operaciones de listado de archivos en el storage son más rápidas. No obstante, el beneficio real viene de combinarlo con OPTIMIZE para reducir el número de peticiones de lectura.
¿Puedo recuperar archivos borrados por VACUUM?
No. Una vez que el comando VACUUM se completa, los archivos se eliminan físicamente de OneLake. La única forma de recuperarlos sería mediante un backup previo o si tienes activada la retención suave (soft delete) a nivel de cuenta de almacenamiento, aunque esto último no es lo estándar en la gestión directa de tablas Delta en Fabric.
¿Con qué frecuencia debo ejecutar la limpieza?
Para la mayoría de los escenarios de Business Intelligence corporativo, una vez por semana es suficiente. Si manejas datos de streaming con miles de actualizaciones por hora, podrías considerar una frecuencia diaria con un periodo de retención de 24 o 48 horas.
¿Es necesario ejecutar VACUUM si mi tabla es de solo inserción (Append-only)?
Generalmente no. Si solo añades datos y nunca haces UPDATE, DELETE o OVERWRITE, todos los archivos Parquet estarán referenciados por la última versión del log y VACUUM no encontrará nada que borrar. Solo sería útil si realizas compactaciones con OPTIMIZE, ya que esta operación sí genera archivos antiguos obsoletos.







