Como fazer backup de PostgreSQL com pg_dump, pg_dumpall e pg_basebackup, incluindo incremental no PostgreSQL 17+, restauração e PITR.
Para que serve
Este artigo mostra duas formas de fazer backup de PostgreSQL rodando no seu servidor dedicado ou em uma VM: o pg_dump, que gera um backup lógico de cada banco (portátil entre versões e ideal para restaurar um banco isolado), e o pg_basebackup, que copia o cluster inteiro a quente (mais rápido para volumes grandes e base para backups incrementais a partir do PostgreSQL 17). Os exemplos usam Debian 12/13 e Ubuntu 24.04 com o pacote oficial.
Pré-requisitos
- Acesso root e ao usuário de sistema
postgres. - Versão do PostgreSQL:
psql --version. Debian 13 traz a 17; Ubuntu 24.04 traz a 16; o repositório PGDG oferece a 18. - Espaço livre em outro volume para pelo menos um backup completo.
Opção 1: pg_dump (backup lógico por banco)
-
Faça o dump de um banco no formato custom. O formato
-Fcjá vem compactado e permite restaurar só algumas tabelas depois.mkdir -p /var/backups/postgres && chown postgres: /var/backups/postgres sudo -u postgres pg_dump -Fc -f /var/backups/postgres/meubanco.dump meubancoO pg_dump lê o banco dentro de uma transação: o resultado é consistente e não bloqueia leituras nem escritas da aplicação.
-
Guarde também os papéis (usuários) e permissões globais. O pg_dump não inclui usuários; sem eles a restauração falha com "role does not exist".
sudo -u postgres pg_dumpall --globals-only -f /var/backups/postgres/globais.sql -
Automatize todos os bancos. Crie
/usr/local/sbin/dump-postgres.sh:#!/bin/bash set -euo pipefail DEST=/var/backups/postgres DATA=$(date +%F_%H%M) sudo -u postgres pg_dumpall --globals-only -f "$DEST/_globais_${DATA}.sql" for db in $(sudo -u postgres psql -At -c "SELECT datname FROM pg_database WHERE datallowconn AND datname <> 'template1'"); do sudo -u postgres pg_dump -Fc -f "$DEST/${db}_${DATA}.dump" "$db" done find "$DEST" -type f -mtime +7 -deletechmod 700 /usr/local/sbin/dump-postgres.sh echo '15 1 * * * root /usr/local/sbin/dump-postgres.sh' > /etc/cron.d/dump-postgresDepois, envie
/var/backups/postgrespara fora do servidor com restic ou rclone.
Restaurar um dump
sudo -u postgres psql -f /var/backups/postgres/_globais_2026-10-08_0115.sql # se for outro servidor
sudo -u postgres createdb -O dono_do_banco meubanco_teste
sudo -u postgres pg_restore -d meubanco_teste -j 4 /var/backups/postgres/meubanco_2026-10-08_0115.dump
O -j 4 restaura em paralelo com 4 processos. Para restaurar só uma tabela, use pg_restore -t nome_da_tabela. Para ver o conteúdo do arquivo sem restaurar, use pg_restore -l ARQUIVO.
Opção 2: pg_basebackup (cópia física do cluster)
O pg_basebackup copia todos os bancos do cluster de uma vez, com o servidor no ar. A restauração é mais rápida que a de um dump, porque não reconstrói índices; em compensação, só restaura na mesma versão principal do PostgreSQL e sempre o cluster inteiro.
-
Confira as permissões de replicação. O usuário precisa do atributo
REPLICATION(opostgresjá tem) e opg_hba.confprecisa permitir conexões de replicação. No Debian/Ubuntu, a linhalocal replication all peerjá vem habilitada. Para usar o pg_basebackup na criação de uma réplica, veja também o artigo «Replicação PostgreSQL em streaming: como configurar com pg_basebackup». -
Faça o backup completo.
sudo -u postgres pg_basebackup -D /var/backups/pgbase/full-$(date +%F) \ -Ft -z -X stream -c fast -P-Ft -z: grava em arquivos tar compactados.-X stream: inclui os WALs gerados durante a cópia, deixando o backup autossuficiente.-c fast: força o checkpoint imediato para começar logo.
-
Restaurar (exemplo com PostgreSQL 17 no Debian):
systemctl stop postgresql@17-main mv /var/lib/postgresql/17/main /var/lib/postgresql/17/main.antigo mkdir -m 700 /var/lib/postgresql/17/main tar -xzf /var/backups/pgbase/full-2026-10-08/base.tar.gz -C /var/lib/postgresql/17/main tar -xzf /var/backups/pgbase/full-2026-10-08/pg_wal.tar.gz -C /var/lib/postgresql/17/main/pg_wal chown -R postgres:postgres /var/lib/postgresql/17/main systemctl start postgresql@17-mainNo Debian, os arquivos de configuração ficam em
/etc/postgresql/17/main, fora do diretório de dados, e não são substituídos pela restauração.
Backups incrementais (PostgreSQL 17 e 18)
A partir da versão 17, o pg_basebackup pode copiar só os blocos alterados desde um backup anterior. Para isso, ative o resumo de WAL:
sudo -u postgres psql -c "ALTER SYSTEM SET summarize_wal = on"
sudo -u postgres psql -c "SELECT pg_reload_conf()"
Faça um backup completo em formato de diretório e, nos dias seguintes, incrementais apontando para o manifesto do anterior:
sudo -u postgres pg_basebackup -D /var/backups/pgbase/full -c fast
sudo -u postgres pg_basebackup -D /var/backups/pgbase/inc1 -c fast \
--incremental=/var/backups/pgbase/full/backup_manifest
Para restaurar, junte a cadeia em um backup completo com o pg_combinebackup e use o resultado como diretório de dados:
sudo -u postgres pg_combinebackup /var/backups/pgbase/full /var/backups/pgbase/inc1 \
-o /var/backups/pgbase/restaurado
Se qualquer elo da cadeia se perder, os incrementais seguintes não servem. Faça um completo novo pelo menos uma vez por semana.
Recuperação até um ponto no tempo (PITR)
Para voltar o banco ao minuto anterior a um erro, é preciso arquivar continuamente os WALs (archive_mode e archive_command) além dos backups de base. Fazer isso à mão é trabalhoso; em produção, prefira ferramentas como pgBackRest ou Barman, que cuidam do arquivamento, da retenção e do envio para S3.
Como testar o backup de PostgreSQL
pg_restore -l ARQUIVO.dump | headlista o conteúdo sem erro.- Para o pg_basebackup, rode
pg_verifybackupno backup em formato de diretório: ele compara os arquivos com o manifesto. - Mensalmente, restaure em um banco ou instância de teste e compare contagens de linhas e a data do registro mais recente.
Problemas comuns
"server version mismatch" no pg_dump
O pg_dump precisa ser da mesma versão ou mais novo que o servidor. Se você instalou várias versões, chame o binário certo, por exemplo /usr/lib/postgresql/17/bin/pg_dump.
"role ... does not exist" ao restaurar
Restaure antes o arquivo de globais, ou use pg_restore --no-owner --role=novo_dono.
"number of requested standby connections exceeds max_wal_senders"
Aumente max_wal_senders no postgresql.conf (o padrão é 10) e reinicie o serviço.
Incremental falha com "WAL summaries are required"
O summarize_wal não estava ativo quando o backup de referência foi feito. Ative-o, faça um completo novo e só depois os incrementais.
Perguntas frequentes
O pg_dump trava o banco durante o backup?
Não. Ele lê tudo dentro de uma transação, então o resultado é consistente e a aplicação continua lendo e gravando normalmente.
O pg_dump copia usuários e senhas?
Não. Os papéis e permissões globais ficam de fora; exporte-os com pg_dumpall --globals-only e restaure esse arquivo antes dos bancos.
Qual a diferença entre pg_dump e pg_basebackup?
O pg_dump é lógico, por banco, e restaura em outras versões. O pg_basebackup copia o cluster inteiro, restaura mais rápido, mas só na mesma versão principal do PostgreSQL.
O PostgreSQL tem backup incremental?
Sim, a partir da versão 17, com pg_basebackup --incremental e o summarize_wal ativado. Para restaurar, junte a cadeia com o pg_combinebackup.
Como restaurar só uma tabela?
Com um dump no formato custom (-Fc), use pg_restore -t nome_da_tabela apontando para um banco de teste.
Leitura complementar
Precisa de ajuda?
Se o backup ou a restauração falhar, abra um ticket na área do cliente com a mensagem de erro e a saída de psql --version.
