- En PostgreSQL, aunque hagas DROP de una columna, los datos en realidad no se eliminan; solo quedan "ocultos" en los metadatos
- Como la columna sigue existiendo internamente incluso después de
DROP COLUMN, puedes llegar al límite de 1600 columnas
- Para eliminar los datos por completo, se necesita
VACUUM FULL o una reescritura manual de la tabla
- Es un diseño pensado para optimizar el rendimiento, pero requiere cuidado desde la perspectiva de cumplimiento normativo, como GDPR
- Entender "qué ocurre realmente" ayuda en la resolución de problemas, optimización de rendimiento y gestión de datos
Cómo funciona realmente DROP COLUMN en PostgreSQL
El problema: ¿qué pasa si agregas y eliminas columnas repetidamente?
¿Qué ocurre dentro de PostgreSQL?
Eliminar una columna no es una "eliminación real"
- PostgreSQL almacena los datos en páginas de 8 KB
- Eliminar físicamente una columna implicaría reescribir toda la tabla, por lo que sería ineficiente
- En su lugar, la columna se marca como 'dropped' en los metadatos y se ignora
Se puede comprobar en la tabla del sistema pg_attribute
SELECT attnum, attname, attisdropped FROM pg_attribute WHERE attrelid = 'test2'::regclass AND attnum > 0;
Comprobarlo en el archivo de datos (usando pg_filedump)
- Si analizas el archivo de datos de PostgreSQL, puedes confirmar que los valores de la columna eliminada siguen ahí
- En los datos antiguos (
Item 1) todavía existen los valores de 3 columnas
- En los datos insertados después de la eliminación (
Item 3), ese valor de columna ya no está y se trata como NULL
Cómo eliminar de verdad una columna eliminada
1. VACUUM FULL
- Reescribe toda la tabla y también elimina los datos de las columnas borradas
- Desventaja: la columna en sí sigue existiendo en
pg_attribute con estado 'dropped'
2. Reescritura manual de la tabla
DROP COLUMN y el problema del "derecho al olvido" en GDPR
Precauciones
- Como PostgreSQL usa MVCC, incluso después de eliminar filas los datos permanecen hasta que
VACUUM termine
- Incluso a nivel de sistema operativo, puede tratarse de una marca de eliminación y no de un borrado físico
- Desde el punto de vista legal, lo importante es hacer un “esfuerzo razonable de eliminación”; en la mayoría de los casos no se exige borrar por completo el disco físico
Conclusión: DROP COLUMN solo "oculta", no "elimina"
- Es un diseño orientado al rendimiento, pero si se acumulan columnas puedes chocar con el límite de 1600
- Si hace falta, se deben limpiar los datos con
VACUUM FULL o una reescritura de la tabla
- Desde la perspectiva de diseño de sistemas o cumplimiento, entender el funcionamiento interno de PostgreSQL resulta muy útil
Material de referencia
3 comentarios
La perspectiva de que una elección de implementación para optimizar el rendimiento también puede pensarse en relación con el problema del derecho al olvido del GDPR es muy perspicaz. Al final, la conclusión es que no está relacionado, y que la clave es modelar y eliminar correctamente los datos personales. Muy limpio.
Aunque
postgresqlestá bastante popular últimamente, en cuanto a la implementación de MVCC prefiero más el enfoque donde existen áreas separadas de redo/undo.Como en las áreas de redo/undo está bien sacrificar en cierta medida la inmediatez, también hay margen para optimizar costos usando almacenamiento de menor nivel.
Y el hecho de que en algún momento haya que bloquear toda la DB y ejecutar
VACUUM FULLtambién es algo que no me gusta.¿Entonces es cierto que en algún momento necesariamente hay que ejecutar
VACUUM FULL? La mayoría de los documentos que vi más bien dicen que no se debe hacer.Uno de los materiales que vi:
https://www.depesz.com/2023/02/06/when-to-use-vacuum-full/