Por que linhas excluídas não reduzem o tamanho do seu banco de dados
A arquitetura de Multi-Version Concurrency Control (MVCC) do PostgreSQLQL, embora fundamental para operações concorrentes de banco de dados, traz um custo inerente: o inchaço de tabelas (table bloat). Quando uma linha é atualizada, o PostgreSQLQL não a modifica no local; em vez disso, grava uma cópia totalmente nova e marca a versão antiga como "morta". Esse mecanismo garante que as transações sempre vejam um snapshot consistente dos dados, mas deixa para trás um rastro de dados obsoletos.
Eventualmente, os processos de VACUUM limpam essas linhas mortas, tornando o espaço delas disponível para novos dados na mesma tabela. Fundamentalmente, uma operação de VACUUM de rotina não devolve esse espaço recuperado ao sistema operacional. Se você excluir metade da tabela, o arquivo em disco frequentemente permanece com o mesmo tamanho, uma fonte comum de frustração para DBAs.
Historicamente, a única forma nativa de reduzir fisicamente uma tabela e devolver espaço ao sistema operacional era o VACUUM FULL. Esse comando reescreve a tabela inteira, compactando-a em novas páginas de disco. No entanto, o VACUUM FULL adquire um bloqueio ACCESS EXCLUSIVE, impedindo todas as leituras e gravações na tabela até sua conclusão — uma consequência tão grave que até a documentação do próprio PostgreSQLQL desaconselha seu uso em ambientes de produção. Isso deixou os DBAs dependentes de extensões de terceiros, como o pg_repack, para a compactação online de tabelas.
O REPACK tira o trabalho pesado do caminho crítico
O PostgreSQLQL 19 finalmente oferece aos DBAs uma solução nativa e online para o inchaço de tabelas: REPACK CONCURRENTLY. Esse comando contorna o VACUUM FULL impeditivo ao criar uma nova versão compacta de uma tabela, permitindo leituras e gravações concorrentes na original. É uma virada de jogo para manter o desempenho sem tempo de inatividade.
O mecanismo é engenhoso: o REPACK primeiro copia todas as linhas ativas para uma nova tabela temporária. Em seguida, e isso é crucial, usa WAL-based logical decoding para capturar quaisquer alterações (inserções, atualizações, exclusões) ocorridas na tabela original durante essa fase de cópia. Essas alterações capturadas são reproduzidas na nova tabela, garantindo que a substituta esteja totalmente atualizada.
Por fim, o REPACK aplica um breve bloqueio exclusivo para trocar atomicamente o arquivo da tabela antiga pelo da nova, compacta. Isso minimiza a janela crítica em que a tabela fica indisponível. O teste da Better Stack mostrou uma tabela de 493 MB reduzida para 228 MB em menos de 10 segundos, permanecendo acessível até a troca final, momentânea. Este não é um benchmark universal, mas destaca a potente economia de disco e a eficiência operacional que o REPACK oferece.
O pequeno bloqueio que pode causar um grande congestionamento de tráfego
O REPACK CONCURRENTLY não faz mágica; ele apenas transfere o trabalho pesado. Embora a maior parte da cópia da tabela ocorra online, a etapa final e crucial — trocar o arquivo da tabela antiga pela nova versão compactada — exige um bloqueio exclusivo. Esse bloqueio ACCESS EXCLUSIVE impede quaisquer operações concorrentes, sejam leituras ou gravações, na tabela. É uma janela minúscula e atômica, mas precisa aguardar a conclusão de cada transação ativa que acessa essa tabela.
Esse gargalo cria um risco operacional significativo. Um teste da Better Stack demonstrou isso perfeitamente: um relatório analítico de 20 segundos, ativo durante a troca, atrasou a substituição final. Isso fez com que todas as consultas subsequentes direcionadas a essa tabela ficassem em fila por 18 segundos completos, criando efetivamente um cenário de head-of-line blocking. A promessa do reempacotamento online fica diminuída se uma única consulta de longa duração puder atrapalhar as operações concorrentes.
Para mitigar isso, trate a troca final como um evento crítico. Agende o REPACK CONCURRENTLY para horários de menor movimento, quando é improvável que relatórios de longa duração ou jobs em lote disputem a tabela. Verifique proativamente se há sessões ativas na tabela de destino antes de iniciar o comando, ou consulte recursos como PostgreSQLQL Documentation: Routine Vacuuming para saber mais sobre o gerenciamento da manutenção de tabelas. O objetivo é garantir que a troca de metadados ocorra sem atrasos inesperados, transformando um truque engenhoso em uma ferramenta operacional confiável.
Gostando do artigo? Receba um assim na sua caixa de entrada toda manhã.
um e-mail por dia · cancele em dois cliques · sem rastreadores de terceiros
Uma ferramenta nativa, não um motivo para dispensar o planejamento
O REPACK CONCURRENTLY nativo do PostgreSQLQL 19 oferece uma alternativa atraente a ferramentas de terceiros como o pg_repack, que é um item básico da comunidade há mais de uma década. O suporte integrado simplifica o gerenciamento de extensões, evita problemas de compatibilidade e potencialmente melhora a integração com as operações centrais do banco de dados. Essa evolução reflete uma tendência crescente de internalizar funcionalidades críticas de DBAs.
No entanto, "nativo" não equivale a "mágico". Embora o vídeo da Better Stack cite uma data de lançamento prevista de November 19 para o PostgreSQLQL 19, os usuários devem verificar o status atual de lançamento e o suporte do provedor antes de planejar qualquer migração. Os serviços gerenciados, em particular, podem atrasar a adoção de recursos ou impor restrições a novos comandos, portanto confirme sempre os recursos disponíveis com o seu fornecedor específico.
O caminho de desenvolvimento do PostgreSQLQL 19 foi, como observa o vídeo, "acidentado", com recursos anunciados, cancelados e reduzidos em favor da estabilidade. Essa abordagem cautelosa é característica do PostgreSQLQL Global Development Group. Portanto, antes de depender do REPACK CONCURRENTLY em cargas de trabalho de produção, confirme seu comportamento preciso e quaisquer ressalvas operacionais na documentação oficial do PostgreSQLQL 19.
Em última análise, o REPACK CONCURRENTLY é uma nova e poderosa flecha na aljava do DBA, não uma solução mágica. Seu breve, porém crítico, bloqueio exclusivo significa que o planejamento estratégico continua essencial. Executá-lo em janelas de baixa atividade ou quando não há consultas de longa duração maximizará seu benefício e evitará o tipo de fila de 18 segundos observado nos testes da Better Stack.
Perguntas frequentes
O que o REPACK faz no PostgreSQL 19?
REPACK reconstrói uma tabela em um layout físico mais compacto, recuperando espaço em disco não utilizado e permitindo que a atividade normal do banco de dados continue.
Qual é a diferença entre REPACK e VACUUM FULL?
VACUUM FULL reescreve uma tabela mantendo um bloqueio impeditivo durante a operação. REPACK CONCURRENTLY realiza a maior parte do trabalho enquanto a tabela permanece acessível e, em seguida, precisa de um breve bloqueio exclusivo para trocar os arquivos.
O REPACK CONCURRENTLY ainda pode afetar o tráfego da aplicação?
Sim. A troca final precisa aguardar a conclusão das consultas que usam a tabela, e novas requisições podem ficar em fila atrás do bloqueio.
O PostgreSQL 19 torna o pg_repack obsoleto?
Pode reduzir a necessidade do pg_repack em alguns casos, mas as equipes devem comparar a disponibilidade e a adequação operacional do recurso nativo com as ferramentas que já utilizam.

