- No PostgreSQL, mesmo ao dar DROP em uma coluna, os dados não são realmente apagados — eles apenas ficam "ocultos" nos metadados
- Como a coluna continua existindo internamente mesmo após o
DROP COLUMN, é possível atingir o limite de 1600 colunas
- Para remover os dados por completo, é necessário usar
VACUUM FULL ou reescrita manual da tabela
- Isso é um design voltado para otimização de desempenho, mas exige atenção do ponto de vista de conformidade, como no GDPR
- Entender "o que realmente acontece" ajuda em resolução de problemas, otimização de desempenho e gerenciamento de dados
Como o DROP COLUMN realmente funciona no PostgreSQL
O problema: e se você adicionar/remover colunas repetidamente?
O que acontece dentro do PostgreSQL?
Remover uma coluna não é uma "remoção de verdade"
- O PostgreSQL armazena dados em páginas de 8 KB
- Remover fisicamente uma coluna exigiria reescrever a tabela inteira, o que seria ineficiente
- Em vez disso, a coluna é marcada como 'dropped' nos metadados e ignorada
Dá para verificar isso na tabela de sistema pg_attribute
SELECT attnum, attname, attisdropped FROM pg_attribute WHERE attrelid = 'test2'::regclass AND attnum > 0;
Verificando no arquivo de dados (com pg_filedump)
- Ao analisar o arquivo de dados do PostgreSQL, é possível confirmar que os valores da coluna removida ainda permanecem lá
- Nos dados antigos (
Item 1), existem valores para 3 colunas
- Nos dados inseridos após a remoção (
Item 3), esse valor de coluna não existe mais e passa a ser tratado como NULL
Como remover de fato uma coluna apagada
1. VACUUM FULL
- Reescreve a tabela inteira e remove também os dados da coluna apagada
- Desvantagem: a própria coluna ainda continua existindo em
pg_attribute, no estado 'dropped'
2. Reescrita manual da tabela
DROP COLUMN e o problema do "direito ao esquecimento" no GDPR
Pontos de atenção
- Como o PostgreSQL usa MVCC, mesmo após apagar uma linha, os dados continuam existindo até que o VACUUM seja concluído
- No nível do sistema operacional, também pode haver apenas um "marcador de exclusão" em vez de remoção física imediata
- Do ponto de vista jurídico, o importante costuma ser um "esforço razoável de exclusão"; apagar completamente o disco físico geralmente não é exigido
Conclusão: DROP COLUMN é mais "ocultar" do que "apagar"
- É uma escolha de design focada em desempenho, mas o acúmulo de colunas pode bater no limite de 1600
- Quando necessário, use
VACUUM FULL ou reescrita da tabela para limpar os dados
- Entender o funcionamento interno do PostgreSQL é muito útil para arquitetura de sistemas e conformidade
Referências
3 comentários
A perspectiva de que uma escolha de implementação para otimização de desempenho também pode ser pensada em relação ao direito ao esquecimento da GDPR é bem perspicaz. No fim, a conclusão é que o essencial é modelar e excluir corretamente os dados pessoais, então não há relação direta. Bem elegante.
Embora o
postgresqlesteja bem popular ultimamente, eu prefiro implementações de MVCC em que as áreas de redo/undo existem separadamente.Como dá para sacrificar um pouco a operação em tempo real nas áreas de redo/undo, também existe espaço para otimizar custos usando armazenamento de categoria mais baixa.
Também não gosto do fato de que, em algum momento, é preciso bloquear o banco de dados inteiro e executar um
VACUUM FULL.Isso significa que, em algum momento, é realmente necessário fazer
VACUUM FULL? Pelo que vi na maioria dos documentos, quase sempre recomendam não fazer isso.Uma das referências que vi:
https://www.depesz.com/2023/02/06/when-to-use-vacuum-full/