Reorganizar uma tabela inchada sem locks longos (pg_repack)
PostgreSQLManutençãoComando
-- Once per target database (the pg_repack package must be installed on the server)
CREATE EXTENSION pg_repack;
# Dry run: show what would be done
pg_repack -h localhost -U postgres -d mydb --table=public.orders --dry-run
# Rewrite the table and its indexes: 2 parallel index builds, wait at most 60 s for locks
pg_repack -h localhost -U postgres -d mydb --table=public.orders --jobs=2 --wait-timeout=60 --no-kill-backend
# Rebuild indexes only
pg_repack -h localhost -U postgres -d mydb --table=public.orders --only-indexesO que faz
Cria em segundo plano uma cópia compactada da tabela, captura as mudanças concorrentes em uma tabela de log por meio de um trigger e troca as tabelas no final sob um breve lock ACCESS EXCLUSIVE; ao contrário do VACUUM FULL, não bloqueia leituras/gravações durante toda a operação.
Quando usar
Quando é preciso recuperar, em um sistema em produção, um bloat severo que o VACUUM não consegue devolver (verificado com pgstattuple).
Atenção
A tabela deve ter uma PRIMARY KEY ou um índice UNIQUE em colunas NOT NULL. Precisa temporariamente de espaço em disco extra igual à tabela mais seus índices e gera WAL pesado (lag de réplicas, volume de archive). Locks ACCESS EXCLUSIVE são necessários no início e no fim; quando --wait-timeout expira, o padrão é cancelar as consultas conflitantes e, se necessário, encerrar suas sessões, enquanto --no-kill-backend pula a tabela. Não execute DDL na tabela alvo durante a execução. As versões do cliente e da extensão devem coincidir. Se for interrompido, limpe os resíduos com DROP EXTENSION pg_repack CASCADE; CREATE EXTENSION pg_repack;