O PostgreSQL 19 prepara um comando REPACK nativo para reescrever uma tabela e seus índices, eliminando espaço ocupado por versões mortas e devolvendo ao sistema operacional o que não precisa permanecer no arquivo. Com CONCURRENTLY, a maior parte do trabalho permite leituras e escritas.
A primeira release candidate foi publicada em 15 de outubro de 2026 e trouxe diversas correções especificamente para o modo concorrente. O PostgreSQL 19 ainda não está em disponibilidade geral: o cronograma divulgado prevê RC2 para 12 de novembro e lançamento para 19 de novembro, se nenhum problema exigir adiamento.
REPACK reescreve em vez de apenas liberar para reuso
O VACUUM comum torna o espaço de tuplas mortas reutilizável pela própria tabela, mas normalmente não reduz seu arquivo no filesystem. REPACK copia as linhas vivas para um novo arquivo, cria novamente os índices, troca os arquivos e remove os antigos.
Sem CONCURRENTLY, o comando mantém um lock ACCESS EXCLUSIVE durante a operação. Com a opção, usa SHARE UPDATE EXCLUSIVE na fase principal, captura alterações simultâneas por logical decoding e solicita ACCESS EXCLUSIVE no final para aplicar o restante e trocar os arquivos.
Concorrente reduz o bloqueio, mas não o elimina
A etapa final ainda precisa de exclusividade. Se outras transações seguram locks incompatíveis, o repack espera e as mudanças capturadas continuam se acumulando. Quando obtém o lock, a duração depende também do volume que restou para aplicar.
A documentação alerta que o modo concorrente não é seguro para snapshots MVCC anteriores ao início da reorganização: depois do commit, essas transações podem enxergar a tabela como vazia. A operação também pode falhar se DDL concorrente alterar a relação.
A cópia exige capacidade temporária
É preciso ter espaço livre ao menos equivalente à soma da tabela e de seus índices. Se USING INDEX levar a um scan seguido de ordenação, o arquivo temporário pode acrescentar até o tamanho da tabela.
No modo concorrente, os dados completos das mudanças ocorridas durante a cópia também são armazenados separadamente. A documentação estabelece ainda um limite aproximado de 104 milhões de linhas atualizadas ou removidas durante a operação.
Nem toda tabela aceita CONCURRENTLY
O modo concorrente exige uma tabela heap registrada, com chave primária e replica identity baseada em índice. Não aceita tabelas particionadas, UNLOGGED, catálogos, TOAST, materialized views ou execução dentro de um bloco de transação. O parâmetro max_repack_replication_slots também deve permitir um slot adicional.
O comando pode usar USING INDEX para reorganizar fisicamente as linhas segundo um índice e recebe a opção ANALYZE para atualizar estatísticas ao final. O progresso aparece em pg_stat_progress_repack.
REPACK não substitui o vacuum rotineiro
A documentação recomenda VACUUM para prevenir wraparound. REPACK é uma reescrita mais longa, pode falhar perto do fim e funciona como uma única transação longa, capaz de atrasar a remoção de versões mortas em outras tabelas.
O recurso deve entrar como ferramenta excepcional para bloat significativo ou clustering, depois de corrigir autovacuum, transações longas ou padrão de retenção que provocaram o crescimento. Adotá-lo não dispensa medir espaço, locks, WAL e impacto nas réplicas.
