Previsão de Crescimento de Armazenamento
Surpresas no disco interrompem escritas: crescimento de tabelas e índices, inchaço, retenção de WAL de slots de replicação e artefatos de backup consomem bytes. Preveja o crescimento mensal a partir de taxas de inserção medidas e saúde do autovacuum, não de uma estimativa de provisionamento inicial.
Receita
-- Tamanhos do banco de dados e das tabelas principais
SELECT pg_size_pretty(pg_database_size(current_database())) AS db_total;
SELECT relname,
pg_size_pretty(pg_total_relation_size(relid)) AS total,
pg_size_pretty(pg_relation_size(relid)) AS heap,
n_live_tup,
n_dead_tup
FROM pg_stat_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 15;-- Tamanho do diretório WAL (auto-hospedado)
SELECT count(*) AS wal_files,
pg_size_pretty(sum(size)) AS wal_bytes
FROM pg_ls_waldir();Quando usar isso:
- Orçamento anual para o limite máximo de autoscale de armazenamento do RDS
- Incidente de inchaço após exclusão em massa ou vacuum falho
- Alerta de slot de replicação de pressão de disco
Exemplo de Trabalho
Preveja o crescimento de 90 dias para a tabela somente de anexação events.
-- Tamanho atual
SELECT pg_relation_size('events') AS bytes,
pg_size_pretty(pg_relation_size('events')) AS pretty;
-- Taxa de inserção diária (de estatísticas ou métricas do aplicativo)
SELECT relname, n_tup_ins, n_tup_upd, n_tup_del, last_autovacuum
FROM pg_stat_user_tables
WHERE relname = 'events';
-- Previsão aproximada: avg_row_bytes × daily_inserts × 90
-- Medir linha média:
SELECT avg(pg_column_size(e)) AS avg_row_bytes FROM events e TABLESAMPLE SYSTEM (1);-- Razão de sobrecarga de índice
SELECT indexrelname,
pg_size_pretty(pg_relation_size(indexrelid)) AS idx_size
FROM pg_stat_user_indexes
WHERE relname = 'events';# Modelo de planilha (conceitual)
# daily_new_bytes = inserts_per_day * (avg_row + index_factor)
# index_factor frequentemente 0.3-1.0 dependendo dos índices
# adicione 25% de margem para inchaço se o autovacuum for marginalO que isso demonstra:
- Tamanho do heap + índices =
pg_total_relation_size n_dead_tupsinaliza risco de inchaço após atualizações em massa- Tamanho do WAL separado dos dados do usuário - monitore os slots
pg_column_sizeamostrado estima o crescimento das linhas
Mergulho Profundo
Componentes de Crescimento
| Componente | Driver |
|---|---|
| Inserções no Heap | Taxa de eventos de negócios |
| Índices | Um btree por índice ~ largura da chave × linhas |
| TOAST | Colunas JSON/texto grandes |
| Inchaço | Tuplas mortas não vacuums |
| WAL em disco | max_wal_size, atraso dos slots de replicação |
| Arquivos temporários | Spills de sort/hash para disco |
Detecção de Inchaço
SELECT schemaname, relname, n_live_tup, n_dead_tup,
round(100.0 * n_dead_tup / NULLIF(n_live_tup + n_dead_tup, 0), 2) AS dead_pct
FROM pg_stat_user_tables
WHERE n_dead_tup > 100000
ORDER BY n_dead_tup DESC;pgstattuple ou pg_squeeze para percentual de inchaço profundo em tabelas suspeitas.
Retenção de WAL de Slot de Replicação
SELECT slot_name, slot_type, active,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal
FROM pg_replication_slots;Slot inativo com WAL retido grande é um incidente de disco esperando para acontecer.
Autoscale Gerenciado
Defina o teto máximo de armazenamento alocado no RDS; alerte em 80% da alocação atual.
Armadilhas
- Autoscale sem teto - conta descontrolada. Correção: limite máximo + paginação em 85% de uso.
- Exclusão em massa sem plano de vacuum - o disco não encolhe; o inchaço cresce. Correção: agendamento de
VACUUM (ANALYZE); exclusão de partições para arquivamento. - Atualização de staging esquecida - cópia de produção dobra o disco em não produção. Correção: subset de dados de staging.
- Explosão de índices - cada nova coluna de filtro adiciona bytes permanentes. Correção: índices parciais, descarte de índices não utilizados via
pg_stat_user_indexes idx_scan. - Slot de replicação lógica em primário ocupado - WAL retido até o consumidor alcançar. Correção: monitore os bytes de atraso do slot; descarte slots obsoletos.
- Previsão apenas pela contagem de linhas - linhas JSON largas diferem 10x. Correção: amostre
pg_column_size.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Particionamento de tabela por tempo | Eventos de anexação pesada | Tabelas de dimensão pequenas |
| Arquivamento para armazenamento frio | Anos de retenção de conformidade | Necessidade de consulta instantânea em todo o histórico |
| pg_repack / pg_squeeze | Inchaço sem bloqueio longo | Janela de manutenção indisponível (planeje mesmo assim) |
| Tablespace separado em disco rápido | Divisão quente vs fria | Complexidade de operação indesejada |
FAQs
Com que frequência prever?
Mensalmente para produtos de crescimento rápido; trimestralmente para OLTP estável.
DELETE libera disco?
Marca tuplas mortas; VACUUM FULL ou repack são necessários para retornar espaço ao SO; autovacuum reutiliza internamente.
Tamanho do WAL é normal?
Limitado por max_wal_size no primário, a menos que os slots retenham; investigue GB+ retidos.
Crescimento do TOAST?
Grandes blobs JSON dominam; considere um armazenamento de objetos externo para blobs > poucos KB.
Crescimento apenas de índices?
Reindexar índices não utilizados; índices parciais para consultas filtradas.
Disco do Cloud SQL?
Redimensionamento automático com alerta; aumento manual para crescimento previsível em etapas.
Armazenamento do pg_dump?
Inclua o crescimento do bucket de backup na previsão financeira; comprima o formato customizado.
Alerta de 90% de disco é suficiente?
Sim para página; 85% de aviso dá tempo antes da parada de escrita em algumas plataformas.
Exclusão de partição vs exclusão de linha?
DROP PARTITION recupera espaço instantaneamente vs milhões de exclusões de linha que causam inchaço.
Quem é o responsável pela planilha de previsão?
DBA/plataforma com entrada do produto sobre o multiplicador esperado de crescimento de usuários.
Relacionados
- Noções Básicas de Capacidade - I/O e RAM
- Slots de Replicação - Retenção de WAL
- Armadilhas de Particionamento - Padrão de arquivamento
- Disco Cheio em pgdata - Runbook de incidentes
- Melhores Práticas de Planejamento de Capacidade - Cadência de revisão
Versões da Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, e PostGIS 3.5+.