Backup PostgreSQL

Backup PostgreSQL: Como Evitar o Backup Fantasma no Cron

O susto mais comum que vejo com backup de PostgreSQL não é a falta de rotina — é descobrir, no dia que você mais precisa, que o cron estava rodando o comando errado há meses e gerando arquivos de backup vazios ou corrompidos. Ninguém percebe porque o job “roda” sem erro visível no log padrão. Vou passar os métodos de backup que realmente uso, mas o foco maior aqui é nos detalhes que causam esse tipo de backup fantasma — porque ter um comando de backup não adianta nada se ele não é testado.

pg_dump: o mais usado, mas com uma pegadinha de autenticação

O comando básico é direto:

pg_dump -U usuario -d banco_de_dados -Fc -f backup.dump

Uso -Fc (formato custom, compactado) em vez de exportar em SQL puro (formato “plain”) por dois motivos práticos: o arquivo fica menor e a restauração com pg_restore pode rodar em paralelo com -j, o que faz diferença real em bancos grandes — restaurar um dump de 40 GB de forma sequencial pode levar a noite toda, em paralelo cai bastante.

Agora a pegadinha que mais derruba automação: se o comando roda via cron sem .pgpass configurado ou variável PGPASSWORD definida, o pg_dump fica esperando digitação de senha numa sessão sem terminal interativo — e simplesmente falha ou trava, sem gerar erro visível se você não estiver monitorando a saída do cron. Configure o arquivo ~/.pgpass (com permissão 600, senão o PostgreSQL ignora o arquivo por segurança) no formato host:porta:banco:usuario:senha antes de automatizar qualquer coisa.

pg_dumpall: pra levar tudo, inclusive usuários e permissões

O pg_dump exporta um banco específico, mas não leva roles, usuários e permissões globais da instância. Se você só usa pg_dump e precisa restaurar num servidor novo do zero, vai descobrir que os usuários não existem mais lá. Pra isso existe o pg_dumpall:

pg_dumpall -U usuario --globals-only > globais.sql

Rodar isso junto com o pg_dump por banco (em vez de um pg_dumpall completo de tudo) é a combinação que uso na maioria dos ambientes: globals separado + dump individual por banco, porque facilita restaurar só um banco específico sem mexer nos outros.

Backup físico (pg_basebackup) e o problema do disco de WAL cheio

Pra bancos grandes ou quando você precisa de réplica de standby, o backup físico com pg_basebackup é o caminho:

pg_basebackup -U usuario_replica -D /caminho/backup -Fp -Xs -P

O incidente real que já resolvi (e que assusta na hora): se o WAL archiving estiver configurado mas o destino dos arquivos de WAL ficar sem espaço em disco, o PostgreSQL para de aceitar novas transações de escrita — o banco trava pra evitar perda de dados, não é bug, é comportamento esperado de segurança. Isso derruba sistema em produção do nada se ninguém monitorar o espaço em disco da pasta de WAL separadamente do espaço do banco em si.

Backups incrementais com Barman ou WAL-G

Pra ambientes que não podem depender só de dump diário, ferramentas como Barman (mais comum em instalações on-premises) ou WAL-G (mais usado em nuvem, integra bem com S3) permitem backup incremental com recuperação ponto a ponto — restaurar o banco exatamente como estava um minuto antes de um erro, não só no estado do último backup diário. É mais complexo de configurar, mas faz diferença real quando o problema é um DELETE sem WHERE às 15h e o próximo backup diário só roda de madrugada.

Testando a restauração — o passo que quase ninguém faz

Isso vale mais que qualquer dica de comando: agende um teste de restauração periódico, mesmo que seja mensal, num servidor separado. Já vi mais de um caso de backup “funcionando” há anos que, na hora de restaurar de verdade, dava erro de versão incompatível (dump feito com uma versão de client mais nova que o pg_restore do servidor de destino) ou de charset/encoding diferente do banco original. Só descobre isso testando — nunca confiando que “rodou sem erro” significa “está restaurável”.

Automatizando com cron sem cair na armadilha do backup fantasma

0 2 * * * pg_dump -U usuario -d banco -Fc -f /backup/banco_$(date +%Y%m%d).dump 2>> /var/log/pg_backup.log

Repare no redirecionamento de erro pro log — sem isso, se o comando falhar, você não vai saber até precisar do backup. Complementar com um script simples que checa o tamanho do arquivo gerado (um dump de poucos KBs pra um banco que deveria ter gigabytes é sinal claro de falha silenciosa) evita boa parte das surpresas.

Perguntas frequentes

Pg_dump trava banco em produção durante o backup?
Não trava escritas normais — o pg_dump usa uma transação com snapshot consistente (MVCC), então o banco continua respondendo. O impacto real é em I/O e CPU durante a execução, que pode ser sentido em bancos muito grandes rodando em hardware limitado.

Qual a diferença prática entre backup lógico e físico?
Lógico (pg_dump) é mais portável entre versões e plataformas, mas mais lento pra restaurar em bancos grandes. Físico (pg_basebackup) é mais rápido de restaurar mas exige mesma versão e arquitetura do PostgreSQL entre origem e destino.

Com que frequência devo rodar backup completo?
Diário é o mínimo razoável pra banco em produção com movimento constante. Se a empresa não tolera perder mais que algumas horas de dados, backup incremental via Barman ou WAL-G é o caminho, não só dump diário.

Se o servidor onde o PostgreSQL roda também precisa de uma rotina de backup mais ampla (não só do banco, mas do sistema todo), vale complementar com o guia de otimização de databases PostgreSQL e, se o ambiente usa containers, com como configurar um ambiente Docker pra isolar o banco de testes de restauração sem mexer em produção.

Posted in Backup.

Patrocinadores

suporte de ti                    marketing digital