VACUUM
geralmente não retorna espaço em disco para o sistema operacional, exceto em alguns casos especiais.
Dos documentos:
A forma padrão de
VACUUM
remove versões de linhas inativas em tabelas e índices e marca o espaço disponível para reutilização futura. No entanto, ele não retornará o espaço para o sistema operacional, exceto no caso especial em que uma ou mais páginas no final de uma tabela ficam totalmente livres e um bloqueio de tabela exclusivo pode ser facilmente obtido. Em contraste,VACUUM FULL
ativamente compacta as tabelas escrevendo uma nova versão completa do arquivo de tabela sem espaço morto. Isso minimiza o tamanho da tabela, mas pode levar muito tempo. Também requer espaço em disco extra para a nova cópia da tabela, até que a operação seja concluída.
A questão é: como esse estado de banco de dados pode one or more pages at the end of a table become entirely free
ser alcançado? Isso pode ser feito via VACUUM FULL
, mas não tenho espaço suficiente para implementá-lo. Então, existem outras possibilidades?
Para devolver espaço ao SO, use
VACUUM FULL
. Enquanto estiver nisso, suponho que você corraVACUUM FULL ANALYZE
. Cito o manual :Minha ênfase em negrito.
CLUSTER
consegue isso, também, como um efeito colateral.Plain
VACUUM
normalmente não atinge seu objetivo ( "uma ou mais páginas no final de uma tabela totalmente gratuita" ). Ele não reordena as linhas e apenas remove as páginas vazias do final físico do arquivo quando surge a oportunidade - como revela sua citação do manual.Você pode obter páginas vazias no final do arquivo físico quando você adiciona
INSERT
um lote de linhasDELETE
antes que outras tuplas sejam anexadas. Ou pode acontecer por coincidência se linhas suficientes forem excluídas.Há também configurações especiais que podem impedir
VACUUM FULL
a recuperação de espaço. Ver:Preparar páginas vazias no final de uma tabela para teste
A coluna do sistema
ctid
representa a posição física de uma linha. Você precisa entender essa coluna:Podemos trabalhar com isso e preparar uma tabela excluindo todas as linhas da última página:
Agora, a última página está vazia. Isso ignora gravações simultâneas. Ou você é o único a escrever nessa tabela ou precisa fazer um bloqueio de gravação para evitar condições de corrida.
A consulta é otimizada para identificar rapidamente as linhas qualificadas. O segundo número de a
tid
é o índice da tupla armazenado como unsignedint2
e65535
é o máximo para esse tipo (2^16 - 1
), portanto, esse é o limite superior seguro.db<>fiddle aqui (reutilizando uma tabela simples de um caso diferente.)
Old sqlfiddle
Ferramentas para medir o tamanho da linha/tabela:
Disco cheio
Você precisa de espaço de manobra no disco para qualquer uma dessas operações. Há também a ferramenta da comunidade
pg_repack
como substituto paraVACUUM FULL
/CLUSTER
. Evita travas exclusivas, mas também precisa de espaço livre para trabalhar. O manual:Como último recurso, você pode executar um ciclo de despejo/restauração. Isso também remove todo o inchaço das tabelas e índices. Pergunta intimamente relacionada:
A resposta ali é bem radical. Se sua situação permitir (sem chaves estrangeiras ou outras referências impedindo a exclusão de linhas) e sem acesso simultâneo à tabela), você pode apenas:
Despeje a tabela em disco conectando de um computador remoto com bastante espaço em disco (
-a
para--data-only
):De um shell remoto, despeje os dados da tabela:
Em uma sessão pg,
TRUNCATE
a tabela:Do shell remoto, restaure para a mesma tabela:
Agora está livre de quaisquer linhas mortas ou inchaço.
Mas talvez você possa ter isso mais simples?
Você pode liberar espaço suficiente no disco excluindo (movendo) arquivos não relacionados?
Você pode
VACUUM FULL
diminuir as tabelas primeiro, uma por uma, liberando espaço em disco suficiente?Você pode executar
REINDEX TABLE
ouREINDEX INDEX
liberar espaço em disco de índices inchados?Faça o que fizer, não seja precipitado . Em caso de dúvida, faça backup de tudo em um local seguro primeiro.