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.
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, standby10.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:
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 slotstandby1, que guarda o WAL até o standby recebê-lo.-R: cria o arquivostandby.signale gravaprimary_conninfoeprimary_slot_nameempostgresql.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.
