Dicas de Backup Seguro com pgBackRest e PostgreSQL

Recentemente precisei configurar um ambiente de backup e restore com pgBackRest no PostgreSQL 17 e resolvi documentar tudo do jeito que realmente acontece no dia a dia de um DBA.

Sem pular etapa.
Sem “isso é óbvio”.
E principalmente: sem aquele backup que “parece que funciona”, mas ninguém nunca testou o restore.

A ideia aqui não é só fazer o backup rodar, mas fazer direito, com:

  • Criptografia dos backups
  • Política de retenção automática
  • WAL funcionando corretamente
  • Backup Full, Diferencial e Incremental
  • Validação, logs e visibilidade do que está acontecendo

Tudo isso em um ambiente PostgreSQL standalone, primeiramente apenas para entender a estrutura.

Ambiente utilizado

  • PostgreSQL 17
  • pgBackRest 2.58
  • Ambiente standalone

Passo 1 – Pré-requisito simples (mas que quebra tudo se esquecer)

Antes de qualquer coisa, o diretório do repositório de backup precisa existir e ter permissão correta.

mkdir -p /var/lib/pgbackrest
chown -R postgres:postgres /var/lib/pgbackrest
chmod 750 /var/lib/pgbackrest

Parece detalhe, mas muita configuração “perfeita” falha exatamente aqui.

Passo 2 – Validações iniciais do ambiente

Sempre valido se estou usando o pg_config correto (principalmente quando há mais de uma versão instalada):

which pg_config
pg_config --version

Isso evita apontar o pgBackRest para uma versão errada do PostgreSQL.

Passo 3 – Gerando a chave de criptografia do repositório

O pgBackRest não gera a chave automaticamente. Você precisa criar uma e guardá-la com carinho.

Geração da chave:

openssl rand -base64 48

Exemplo de chave:

vHELRc1VKP7g9Nx5JsE3QMHzt+Eb2jnBRbGhETpYHaXDjznzXaIkhGl3OfxcxY3m

Essa chave será usada no parâmetro repo1-cipher-pass.

Passo 4 – Configurando o arquivo pgbackrest.conf

Com a chave gerada, configuramos o arquivo de configuração do pgBackRest.

Exemplo real usado no ambiente:

[global]
repo1-cipher-pass=vHELRc1VKP7g9Nx5JsE3QMHzt+Eb2jnBRbGhETpYHaXDjznzXaIkhGl3OfxcxY3m
repo1-cipher-type=aes-256-cbc
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2
repo1-retention-diff=1
log-level-console=info
log-level-file=debug

[demo]
pg1-path=/var/lib/pgsql/17/data

Aqui já deixamos definido:

Repositório criptografado (AES-256)

Retenção automática

Logs para troubleshooting

Caminho do PGDATA

Passo 5 – O que é a stanza (e por que ela é tão importante)

A stanza é a identidade do ambiente dentro do pgBackRest ela liga: PostgreSQL, repositório, configuração, histórico de backups.

Criando a stanza:

sudo -u postgres pgbackrest --stanza=demo stanza-create

Se isso falhar, não adianta seguir, primeiro resolve a stanza, depois o resto.

Passo 6 – Configurando o archive_command no PostgreSQL

Sem WAL, não existe restore confiável.

No postgresql.conf: configure o archive mode e o archive command conforme abaixo.

archive_mode = on
archive_command = 'pgbackrest --stanza=demo archive-push %p'

Depois disso, reinicie o serviço do postgres:

systemctl restart postgresql-17.service


Passo 7 – Check da stanza

Antes de qualquer backup, sempre valido:

pgbackrest --stanza=demo check

Esse comando valida que:

PostgreSQL está acessível, WAL está funcionando, repositório responde corretamente

Passo 8 – Backup Full

Agora sim, o primeiro backup de verdade:

pgbackrest --stanza=demo --type=full backup

Esse é o backup base para todos os outros (diff e incr).

Passo 9 – Validando o backup

Nunca confie só no “completed successfully”.

[root@postgres ~]# pgbackrest info
stanza: demo
    status: ok
    cipher: aes-256-cbc

    db (current)
        wal archive min/max (17): 00000001000000000000000B/00000003000000000000001C

        full backup: 20260222-142958F
            timestamp start/stop: 2026-02-22 14:29:58-03 / 2026-02-22 14:30:16-03
            wal start/stop: 000000010000000000000012 / 000000010000000000000012
            database size: 65.5MB, database backup size: 65.5MB
            repo1: backup set size: 9.3MB, backup size: 9.3MB

        diff backup: 20260222-142958F_20260222-145511D
            timestamp start/stop: 2026-02-22 14:55:11-03 / 2026-02-22 14:55:15-03
            wal start/stop: 000000010000000000000018 / 000000010000000000000018
            database size: 72.9MB, database backup size: 7.5MB
            repo1: backup set size: 10.3MB, backup size: 1015.7KB
            backup reference total: 1 full

        incr backup: 20260222-142958F_20260227-154605I
            timestamp start/stop: 2026-02-27 15:46:05-03 / 2026-02-27 15:46:10-03
            wal start/stop: 00000002000000000000001C / 00000002000000000000001C
            database size: 83.4MB, database backup size: 10.6MB
            repo1: backup set size: 11.7MB, backup size: 1.3MB
            backup reference total: 1 full, 1 diff

Aqui você valida:

Tipo do backup, tamanho, data, cadeia de dependência

Passo 10 – Backup Diferencial

O diferencial copia tudo que mudou desde o último full:

pgbackrest --stanza=demo --type=diff backup


Passo 11 – Backup Incremental

O incremental copia apenas o que mudou desde o último backup (full ou diff):

pgbackrest --stanza=demo --type=incr backup

Esse tipo de backup é rápido, leve e ideal para janelas curtas.

Passo 12 – Logs e observabilidade

Quando algo dá errado, o log será seu melhor amigo e voce consegue acompanhar ele:

tail -100 /var/log/pgbackrest/demo-backup.log


Passo 13 – Estrutura dos backups no repositório

Vale a pena entender como os backups ficam organizados:

ls -l /var/lib/pgbackrest/backup/demo/
total 8
drwxr-x---. 3 postgres postgres   72 Feb 22 14:30 20260222-142958F
drwxr-x---. 3 postgres postgres   72 Feb 22 14:55 20260222-142958F_20260222-145511D
drwxr-x---. 3 postgres postgres   72 Feb 27 15:46 20260222-142958F_20260227-154605I
drwxr-x---. 3 postgres postgres   18 Feb 22 14:30 backup.history
-rw-r-----. 1 postgres postgres 2736 Feb 27 15:46 backup.info
-rw-r-----. 1 postgres postgres 2736 Feb 27 15:46 backup.info.copy
lrwxrwxrwx. 1 postgres postgres   33 Feb 27 15:46 latest -> 20260222-142958F_20260227-154605I

Isso ajuda muito na hora de troubleshooting ou restore manual, e como interpretar cada backup, segue abaixo para nao se perder.

20260222-142958F
Esse é o backup Full.
Ele é a base de tudo. Backups diferenciais e incrementais sempre dependem dele.

20260222-142958F_20260222-145511D
Backup Diferencial (Diff).
Contém todas as mudanças desde o último Full (20260222-142958F).

20260222-142958F_20260227-154605I
Backup Incremental (Incr).
Contém apenas o que mudou desde o último backup executado (seja full ou diff).
É o mais leve e rápido.

backup.history
Histórico de backups antigos que já expiraram conforme a política de retenção.
Útil para auditoria e entendimento do ciclo de vida dos backups.

backup.info
Arquivo principal de metadados do repositório.
O pgBackRest usa isso para saber quais backups existem, dependências e validade.

backup.info.copy
Cópia de segurança do backup.info.
Se algo corromper o arquivo principal, essa cópia pode salvar o dia.

latest
Link simbólico apontando para o backup mais recente válido.
Facilita muito na hora de restore, principalmente em cenários de incidente.

No próximo post, vamos realizar Restore Full, Restore usando backup Incremental, Restore pontual de banco (--db-include), o que validar antes, durante e depois do restore.

Deixe um comentário