← Voltar ao blog
    Banco de Dados8 min
    Postgres ocupando muito disco e bloat

    Postgres ocupando muito disco e bloat.

    Quando o cenário é banco postgres crescendo muito, postgres ocupando muito disco, vacuum analyze, autovacuum e postgres bloat, o erro mais comum é culpar apenas o volume de dados. Em ambiente crítico, quase sempre o crescimento anormal tem relação com acúmulo de versões mortas, estatísticas desatualizadas, autovacuum mal calibrado ou operações de escrita que se degradaram sem observabilidade suficiente. O disco enche como sintoma. O problema real costuma estar no ciclo de manutenção do PostgreSQL.

    Em produção, isso não é detalhe operacional. É risco direto de indisponibilidade, aumento de latência, degradação de índice, backup maior, replicação mais lenta e janela de recuperação mais cara. Quando o banco cresce além do esperado, a pergunta correta não é apenas quanto ele cresceu. A pergunta é por que o mecanismo interno de limpeza não está acompanhando a taxa de mudança.

    Por que o Postgres cresce mesmo sem tanto dado novo

    PostgreSQL trabalha com MVCC. Isso significa que updates e deletes não removem imediatamente a versão anterior da linha. Em vez disso, novas versões são criadas e as antigas ficam marcadas para limpeza posterior. Esse comportamento é essencial para consistência transacional, mas cobra disciplina operacional.

    Se a carga tem muito update, tabelas quentes, filas transacionais, integrações que regravam status ou rotinas de expurgo mal planejadas, o espaço ocupado pode crescer muito mais rápido do que o volume líquido de dados de negócio. O banco parece inflar sem explicação aparente. Na prática, é bloat.

    O problema piora quando existem transações longas, queries segurando snapshots por tempo excessivo, replication slots sem controle, jobs de ETL mal comportados ou parâmetros de autovacuum genéricos para uma carga que já saiu do padrão. Em empresas de pagamentos, varejo digital e plataformas com pico intenso de escrita, isso aparece com frequência.

    O que é postgres bloat na prática

    Postgres bloat é o desperdício de espaço em tabelas e índices causado por fragmentação e acúmulo de tuplas mortas que ainda não foram reaproveitadas de forma eficiente. Nem todo crescimento é bloat, mas muito disco ocupado sem aumento proporcional de dados úteis quase sempre aponta nessa direção.

    Em tabela, o bloat surge principalmente por update e delete recorrentes. Em índice, ele também aparece quando há muita mudança em colunas indexadas, churn elevado de linhas e manutenção insuficiente. O efeito visível é simples: mais páginas para ler, mais I/O, cache menos eficiente, planos piores e tempo de resposta subindo aos poucos até virar incidente.

    Esse é um ponto importante para liderança técnica. Bloat raramente explode de uma vez. Ele se acumula em silêncio. Por isso, times sem monitoramento orientado a banco de dados geralmente descobrem tarde, quando o storage já entrou em zona de risco.

    Onde vacuum analyze e autovacuum entram

    O autovacuum existe para evitar exatamente esse acúmulo. Ele limpa tuplas mortas, atualiza mapas de visibilidade e, com ANALYZE, renova estatísticas que o otimizador usa para escolher planos. Sem isso, o PostgreSQL perde eficiência em duas frentes ao mesmo tempo: armazenamento e execução.

    Vacuum não devolve espaço para o sistema operacional na maior parte dos casos. Ele torna o espaço interno reutilizável pelo próprio banco. Isso é suficiente em muitos ambientes, desde que o processo aconteça no ritmo certo. Quando não acontece, o banco segue crescendo fisicamente porque precisa alocar novas páginas enquanto carrega lixo antigo que ainda não foi reaproveitado.

    Já o ANALYZE tem outro papel crítico. Se as estatísticas estão ruins, o otimizador erra cardinalidade, escolhe joins inadequados, usa índice quando não deveria ou faz seq scan em volume desnecessário. Em ambiente com disco pressionado, plano ruim acelera o colapso.

    Quando o autovacuum não dá conta

    Muita operação confia no padrão de fábrica do PostgreSQL como se ele fosse suficiente para qualquer carga. Não é. Os parâmetros default foram pensados para comportamento genérico, não para uma aplicação com alta taxa de update, milhares de TPS ou tabelas com distribuição muito desigual de escrita.

    O autovacuum costuma falhar por cinco motivos recorrentes. O primeiro é escala factor alto demais para tabelas muito grandes. O segundo é custo de I/O limitado em excesso, que torna a limpeza lenta. O terceiro é concorrência com workload pesado, fazendo o processo andar sempre atrás do problema. O quarto são transações longas impedindo remoção efetiva de versões antigas. O quinto é falta de tuning por tabela, tratando objetos frios e quentes como se fossem iguais.

    Também existe um erro de gestão frequente: desligar autovacuum em tabela específica para "ganhar performance" e esquecer de reverter. Em produção séria, isso é convite para crise. Ganho pontual de throughput pode virar expansão descontrolada de storage, degradação de índices e parada não planejada.

    Como diagnosticar banco postgres crescendo muito

    O diagnóstico correto precisa separar crescimento legítimo de crescimento patológico. Se houve onboarding de clientes, retenção regulatória maior, aumento de catálogo ou expansão de histórico transacional, o disco pode ter crescido por razão de negócio. O problema é quando a curva física sobe sem equivalência no dado útil.

    O primeiro passo é identificar quais tabelas e índices estão crescendo mais rápido. Depois, comparar tamanho total, volume de linhas vivas, volume estimado de tuplas mortas e frequência de vacuum e analyze. Em paralelo, vale verificar idade de transações, sessões longas, comportamento de checkpoints, WAL acumulado, slots de replicação e padrão de updates por tabela.

    Se uma tabela tem escrita intensa e autovacuum quase não roda, existe um descompasso claro. Se autovacuum roda, mas as tuplas mortas continuam altas, o problema pode ser transação longa ou tuning insuficiente. Se os índices estão desproporcionalmente grandes, a discussão deixa de ser apenas vacuum e passa a incluir rebuild controlado.

    O que fazer sem aumentar o risco em produção

    A resposta não é sair executando VACUUM FULL em horário comercial. VACUUM FULL reescreve tabela, exige lock pesado e pode transformar um problema de crescimento em indisponibilidade imediata. Em ambiente crítico, a escolha do remédio precisa considerar janela, replicação, taxa de escrita e impacto transacional.

    Na maior parte dos casos, o caminho seguro começa com correção de causa. Ajustar autovacuum por tabela, revisar thresholds, elevar capacidade de limpeza, remover transações longas e atualizar estatísticas costuma estabilizar o crescimento. Quando o bloat já está avançado, pode ser necessário combinar isso com reindex, recreação controlada de objetos ou reorganização planejada.

    Particionamento também entra nessa discussão quando existe retenção temporal ou churn concentrado em dados recentes. Ele não resolve tudo, mas reduz o raio de impacto e melhora previsibilidade de manutenção. O ponto central é não tratar storage como recurso infinito. Quando o banco cresce sem governança, o custo explode antes do disco acabar.

    Sinais de que o problema já saiu do nível tático

    Se o backup está demorando mais a cada semana, a réplica atrasa em horários de pico, queries simples ficaram instáveis e o volume de disco cresce mesmo com expurgo regular, o tema já não é ajuste fino. É risco operacional real.

    Outro sinal grave é quando o time começa a adicionar storage repetidamente sem explicar a causa raiz. Comprar disco adia a crise, mas não corrige bloat, não melhora plano de execução e não reduz I/O desperdiçado. Em ambientes de alta criticidade, esse tipo de improviso custa caro em performance, previsibilidade e recuperação de incidente.

    Também merece atenção o caso em que o banco enche por WAL, não por tabela principal. A causa aí pode ser retenção indevida por replicação lógica, falha de consumo de slot ou archiving inconsistente. Parece outro problema, mas para quem vê apenas o disco do servidor, o sintoma é o mesmo: postgres ocupando muito disco.

    A abordagem certa para ambientes críticos

    Ambiente crítico não aceita manutenção reativa e muito menos tentativa e erro. O que funciona é observabilidade contínua, baseline de crescimento, leitura de catálogos internos, revisão de parâmetros conforme perfil de escrita e runbook claro para contenção. Isso vale especialmente para fintechs, e-commerces e operações que não podem discutir armazenamento no meio de uma degradação.

    Em operações maduras, vacuum analyze e autovacuum não são tarefas de rotina genérica. São mecanismos centrais de continuidade. Eles precisam estar alinhados ao comportamento real da aplicação, ao desenho de índices, à política de retenção e ao volume de transações concorrentes.

    A HTI Tecnologia costuma encontrar esse padrão em ambientes que já passaram da fase de crescimento simples e entraram em escala operacional. O banco não cresce apenas porque o negócio cresceu. Ele cresce porque a manutenção deixou de acompanhar a carga. Quando isso acontece, o custo aparece em disco, mas o impacto real recai sobre SLA, latência e capacidade de recuperação.

    Se o seu PostgreSQL está expandindo mais rápido do que a aplicação justifica, trate isso como desvio operacional, não como detalhe de infraestrutura. Banco de dados saudável reaproveita espaço, mantém estatísticas úteis e limpa versões mortas no ritmo da escrita. Quando esse ciclo quebra, o disco é só o primeiro alarme.

    Sua privacidade importa

    Utilizamos cookies e tecnologias semelhantes para melhorar sua experiência, personalizar conteúdo e analisar o tráfego do site, conforme a LGPD (Lei nº 13.709/2018). Você pode gerenciar suas preferências a qualquer momento.