---
title: "Backup de PostgreSQL não existe até que você consiga restaurar em outra máquina"
author: "Pedro Dalben"
date: "2026-09-19T11:01:47Z"
category: "DevOps & Cloud"
reading_time: "7 min"
canonical: "https://pedrodalben.com.br/blog/backup-de-postgresql-nao-existe-ate-que-voce-consiga-restaurar-em-outra-maquina"
---

# Backup de PostgreSQL não existe até que você consiga restaurar em outra máquina

> A disputa entre pg_dump diário e PITR contínuo ignora a realidade dura de operar PostgreSQL em VPS: se a restauração não é testada, o backup é farsa.

**Autor:** Pedro Dalben (CTO no Integrar Plus)  
**Publicado em:** 19 de September de 2026  
**URL Canônica Oficial:** [https://pedrodalben.com.br/blog/backup-de-postgresql-nao-existe-ate-que-voce-consiga-restaurar-em-outra-maquina](https://pedrodalben.com.br/blog/backup-de-postgresql-nao-existe-ate-que-voce-consiga-restaurar-em-outra-maquina)  

---


Ter um arquivo de duzentos gigabytes salvo em um bucket de armazenamento não significa que sua empresa possui backup. Significa apenas que você gasta dinheiro guardando bytes que podem falhar no momento exato em que a produção desaparecer.

A maioria dos times de infraestrutura só descobre a diferença prática entre fazer cópia de segurança e recuperar dados durante um incidente com o serviço fora do ar. O debate técnico costuma se dividir em dois grupos barulhentos.

De um lado estão os defensores do minimalismo cego: um script rápido no cron disparando `pg_dump` toda madrugada, compactando o arquivo com gzip e enviando o tarball para a nuvem. O argumento dessa turma é a portabilidade, a simplicidade de execução e o fato de que qualquer desenvolvedor júnior sabe rodar um comando para cuspir o esquema.

Do outro lado estão os puristas corporativos que desprezam qualquer solução que não utilize Barman ou pgBackRest com arquivamento contínuo de Write-Ahead Logs (WAL) e recuperação ponto a ponto a cada segundo. Para esse grupo, quem usa dump lógico está brincando de tecnologia e deveria ser banido de ambientes de produção.

A maioria dos defensores do `pg_dump` exclusivo está redondamente enganada, mas o purismo do PITR também costuma criar armadilhas operacionais graves quando aplicado sem critério em servidores próprios.

### A ilusão perigosa do dump lógico diário

O `pg_dump` é uma ferramenta de exportação lógica, não uma estratégia de continuidade de negócio para bases vivas. Quando você roda um dump em uma base de dados ativa com dezenas de tabelas recebendo escrita, o PostgreSQL mantém uma transação longa com nível de isolamento serializável ou snapshot. Isso gera três problemas imediatos.

Primeiro, transações longas impedem que o processo de autovacuum limpe registros mortos nas tabelas mais quentes, inflando o tamanho das páginas em disco e degradando a memória temporária.

Segundo, o RPO (Recovery Point Objective) de um dump diário é inaceitável para quase qualquer negócio sério. Se o seu banco corromper às 18h e o último dump ocorreu às 3h da manhã, você perdeu quinze horas de transações de clientes. Tentar reconciliar isso via logs de aplicação ou eventos perdidos é um pesadelo manual que custa dias de trabalho e credibilidade.

Terceiro, e mais grave: restaurar um dump lógico de centenas de gigabytes é dolorosamente lento. O `pg_restore` precisa recriar cada índice, validar restrições de chave estrangeira e rodar verificações linha por linha. O que levou quarenta minutos para ser extraído pode levar seis, oito ou doze horas para ser reconstruído em um servidor novo sob estresse. Enquanto isso, o sistema permanece inacessível.

Além disso, o `pg_dump` padrão não exporta usuários, senhas, papéis globais nem configurações de cluster. Sem o `pg_dumpall --globals-only`, você restaura as tabelas, mas sua aplicação Rails não consegue sequer autenticar no banco novo porque o usuário da conexão simplesmente não existe.

### As armadilhas de operar PITR no braço em VPS

Reconhecendo as limitações do dump, muitos engenheiros correm para o extremo oposto e tentam configurar Point-in-Time Recovery (PITR) na unha em servidores virtuais privados. É aqui que o consenso da documentação oficial quebra contra a realidade da infraestrutura enxuta.

Para que o PITR funcione, o PostgreSQL precisa arquivar cada segmento de 16 MB de WAL assim que ele é fechado. O mecanismo padrão é o parâmetro `archive_command` no `postgresql.conf`:

```ini
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /mnt/wal_archive/%f && cp %p /mnt/wal_archive/%f'
```

O perigo invisível dessa abordagem reside no comportamento do motor quando o comando de cópia falha. Se o destino do arquivo encher, se a conexão de rede oscilar ou se o script travar por falta de timeout, o PostgreSQL não descarta os arquivos de log. Ele os mantém na pasta local `pg_wal`.

Em poucos minutos de escrita pesada, a partição do banco enche cem por cento. Quando o disco zera o espaço disponível, o PostgreSQL executa um shutdown de emergência para evitar corrupção. O sistema que deveria proteger contra desastres acaba derrubando o ambiente produtivo em uma noite de tráfego intenso.

Eu já enfrentei servidores paralisados porque o script de sincronização de WAL para um bucket S3 compatível acumulou processos zumbis por falta de tratamento de sinais no shell. Ferramentas como o pgBackRest resolvem boa parte dessa complexidade ao gerenciar retries, compressão paralela e remoção de WALs antigos, mas elas exigem um servidor dedicado de backup ou configuração cuidadosa de credenciais e permissões no host.

### A estratégia viável: base física periódica com streaming de WAL

Em nossa infraestrutura, adotamos um caminho que equilibra a velocidade de recuperação com a simplicidade operacional. Em vez de depender exclusivamente de um arquivo lógico ou montar um cluster complexo de ferramentas corporativas, separamos o processo em duas camadas mecânicas.

A primeira camada é a cópia física do cluster usando `pg_basebackup`. Esse utilitário copia os blocos binários do diretório de dados enquanto o banco continua rodando, sem bloquear escritas normais e sem forçar reconstrução de índices na hora da restauração:

```bash
pg_basebackup -h 127.0.0.1 -U replicador -D /backups/base_$(date +%Y%m%d) -Ft -z -P
```

A segunda camada é a recepção contínua dos registros de transação via streaming, utilizando o utilitário `pg_receivewal` rodando como serviço em uma máquina separada na mesma rede privada. Ele se conecta via protocolo de replicação e grava os WALs em tempo real, eliminando a dependência do comando de arquivo síncrono no servidor principal.

Se o banco produtivo sofrer uma pane catastrófica, o procedimento de recuperação exige apenas descompactar o último `pg_basebackup`, apontar o diretório de arquivos WAL recuperados e iniciar o serviço definindo o momento exato de parada com o arquivo de controle `recovery.signal`:

```ini
restore_command = 'cp /storage/wal/%f %p'
recovery_target_time = '2026-09-19 14:22:00-03'
recovery_target_action = 'promote'
```

A restauração de uma base física leva apenas o tempo de descompactação e leitura sequencial de disco, permitindo voltar o sistema em minutos, não em horas.

### O teste automatizado que separa a teoria da realidade

Nada do que descrevi acima tem valor se o processo não for executado do início ao fim longe do ambiente de produção. Um backup não testado tem exatamente o mesmo valor de um backup inexistente. Arquivos corrompem na transferência, permissões mudam em atualizações de sistema operacional e diretórios ficam órfãos sem aviso.

Em vez de confiar em notificações de sucesso no terminal, mantemos uma rotina automatizada semanal que provisiona uma VPS temporária descartável, baixa a base física mais recente, aplica os WALs acumulados, inicia o processo do PostgreSQL e executa uma bateria de verificações de sanidade:

```bash
## Sobe o banco restaurado na máquina de testes
pg_ctl -D /var/lib/postgresql/data_teste start

## Executa consulta de integridade básica via socket local
psql -d app_production -c "SELECT count(*) FROM users;"
psql -d app_production -c "SELECT amcheck_test_indexes();"
```

Usamos a extensão `amcheck` nativa do PostgreSQL para verificar a integridade estrutural das páginas dos índices B-tree. Se o script encontrar corrupção silenciosa ou discrepância de leitura, o alarme soa muito antes de precisarmos desse arquivo em uma emergência.

Admito que essa rotina de validação automatizada consome largura de banda e exige uma máquina temporária para rodar o teste, o que adiciona alguns dólares à fatura mensal de hospedagem. Também reconheço que, para bases que ultrapassam vários terabytes, a transferência contínua de blocos exige planejamento rigoroso de taxa de transferência de disco e conexões de rede interna.

Mesmo com esses custos operacionais, o preço de validar um desastre simulado toda semana é infinitamente menor do que o desespero de descobrir, às quatro da manhã de um domingo, que seu arquivo compactado de backup contém apenas mensagens de erro de permissão negada.
