Monte uma réplica PostgreSQL em streaming com pg_basebackup e replication slot, acompanhe o atraso e promova o standby em caso de falha.

Para que serve

A replicação PostgreSQL em streaming envia o WAL (o registro de alterações) do servidor primário para um standby, que aplica as mudanças continuamente e pode ser usado para consultas de leitura. Se o primário falhar, o standby é promovido em segundos. Este artigo monta uma réplica física com pg_basebackup e replication slot no Debian/Ubuntu, com PostgreSQL 16, 17 ou 18.

Replicação não é backup. Um comando destrutivo no primário é aplicado no standby quase na hora. Mantenha backups e retenção de WAL (veja a categoria Backup e migração).

Pré-requisitos

  • Dois servidores ou VMs com a mesma versão principal do PostgreSQL, mesma arquitetura e pacotes do mesmo repositório (Debian/Ubuntu ou PGDG).
  • Rede privada entre eles. Nos exemplos: primário 10.0.0.21, standby 10.0.0.22, versão 17. Se os dois servidores dedicados estiverem no mesmo datacenter, a E-Consulters pode colocá-los na mesma VLAN (cada servidor tem a sua por padrão): peça por ticket. Em datacenters diferentes, use uma VPN WireGuard entre eles.
  • Porta 5432 liberada apenas entre os dois IPs.
  • Espaço em disco no standby igual ou maior que o do primário.

1. Prepare o primário

Os padrões atuais já atendem a maior parte: wal_level = replica, max_wal_senders = 10 e hot_standby = on. Ajuste o endereço de escuta e um limite de segurança para slots:

cat > /etc/postgresql/17/main/conf.d/92-replicacao.conf <<'EOF'
listen_addresses = 'localhost,10.0.0.21'
max_slot_wal_keep_size = 50GB
wal_keep_size = 1GB
EOF

Crie o usuário de replicação (o createuser pede a senha de forma interativa):

sudo -u postgres createuser --replication -P replicador

Libere o acesso em /etc/postgresql/17/main/pg_hba.conf, exigindo TLS e senha SCRAM:

hostssl  replication  replicador  10.0.0.22/32  scram-sha-256

Reinicie (mudança de listen_addresses exige restart):

systemctl restart postgresql@17-main

No Debian/Ubuntu, o pacote já habilita TLS com certificado autoassinado (ssl = on), suficiente para criptografar o tráfego na rede interna.

2. Crie o standby com pg_basebackup

No standby, com o PostgreSQL instalado, pare o serviço e esvazie o diretório de dados do cluster padrão:

Atenção: o comando abaixo apaga os dados do PostgreSQL do standby. Confira duas vezes se você está no servidor certo (hostname).
systemctl stop postgresql@17-main
rm -rf /var/lib/postgresql/17/main/*

Copie os dados do primário, criando o slot e a configuração de standby automaticamente:

sudo -u postgres pg_basebackup \
  -h 10.0.0.21 -U replicador \
  -D /var/lib/postgresql/17/main \
  -X stream -C -S standby1 -R -P
  • -X stream: transmite o WAL gerado durante a cópia, para o backup ficar consistente.
  • -C -S standby1: cria no primário o replication slot standby1, que guarda o WAL até o standby recebê-lo.
  • -R: cria o arquivo standby.signal e grava primary_conninfo e primary_slot_name em postgresql.auto.conf.
  • -P: mostra o progresso.

Para não digitar a senha, crie um ~postgres/.pgpass com a linha 10.0.0.21:5432:replication:replicador:SENHA e permissão 600. Crie o arquivo antes do pg_basebackup: com -R, o primary_conninfo gerado passa a referenciá-lo.

Inicie o standby:

systemctl start postgresql@17-main

3. Confira a replicação PostgreSQL

No primário:

SELECT client_addr, state, sync_state, sent_lsn, replay_lsn,
       write_lag, flush_lag, replay_lag
FROM pg_stat_replication;

Você deve ver o IP do standby com state = streaming. No standby:

SELECT pg_is_in_recovery();                         -- deve retornar t
SELECT status, sender_host FROM pg_stat_wal_receiver;  -- streaming
SELECT now() - pg_last_xact_replay_timestamp() AS atraso;

O atraso calculado pelo horário só faz sentido quando há escrita no primário; em bancos parados ele cresce sem significar problema. Teste prático: crie uma tabela no primário e consulte-a no standby.

4. Cuide dos replication slots

O slot garante que o standby não perca WAL, mas, se o standby ficar desligado, o primário acumula WAL até encher o disco. O max_slot_wal_keep_size configurado no passo 1 limita esse acúmulo: passado o limite, o slot é invalidado e o standby precisará ser recriado, mas o primário continua de pé. Monitore:

SELECT slot_name, active, wal_status,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retido
FROM pg_replication_slots;

Se desativar um standby de vez, apague o slot: SELECT pg_drop_replication_slot('standby1');.

5. Promover o standby (failover)

Se o primário cair e não voltar, promova o standby:

sudo -u postgres psql -c "SELECT pg_promote();"

Ele passa a aceitar escrita. Aponte a aplicação para o novo IP (ou mova um IP virtual). Nunca deixe o primário antigo voltar como primário ao mesmo tempo: os dois aceitariam escrita e os dados divergiriam (split-brain). Para reintegrá-lo como standby, use pg_rewind ou recrie-o com pg_basebackup.

Para failover automático, ferramentas como Patroni e repmgr gerenciam a eleição e a troca; elas exigem planejamento próprio.

Opcional: replicação síncrona

Com synchronous_standby_names = 'standby1' no primário (e application_name=standby1 no primary_conninfo), cada commit espera a confirmação do standby: zero perda de dados em falha, mas mais latência. Se o standby cair, as gravações no primário param até que ele volte ou a configuração seja removida. Use apenas com dois ou mais standbys ou com monitoramento rigoroso.

Problemas comuns

"no pg_hba.conf entry for replication connection"

A linha do pg_hba.conf precisa ter replication na coluna de banco (não all) e o IP correto. Após editar, rode SELECT pg_reload_conf(); no primário.

"requested WAL segment has already been removed"

O standby ficou para trás e o WAL necessário foi descartado. Recrie o standby com pg_basebackup e use slot.

Consultas longas no standby são canceladas

Erro canceling statement due to conflict with recovery. Aumente max_standby_streaming_delay no standby ou ative hot_standby_feedback = on. Esta última opção impede o primário de limpar linhas que o standby ainda lê, o que pode causar bloat; veja autovacuum e bloat no PostgreSQL.

Perguntas frequentes

Posso escrever no standby?

Não. Ele aceita só leitura até ser promovido.

Replicação física ou lógica?

A física (este artigo) copia o cluster inteiro e é a escolha para alta disponibilidade. A lógica (publicação/assinatura) replica tabelas escolhidas e permite versões diferentes, útil em migrações e upgrades.

Quantos standbys posso ter?

Vários, limitados por max_wal_senders e pela banda de rede. Cada um precisa de seu próprio slot.

Leitura complementar

Precisa de ajuda?

Se a cópia inicial estiver lenta ou a conexão entre os servidores apresentar falhas, abra um ticket com os IPs envolvidos e o resultado de mtr entre eles.

Esta resposta lhe foi útil? 0 Usuários acharam útil (0 Votos)

Leia também