Introdução
A replicação de base de dados garante a durabilidade e a disponibilidade dos dados ao manter cópias em vários servidores. Em sistemas de produção, a replicação não é opcional — é essencial para recuperação de desastre, escalabilidade de leituras e manutenção sem tempo de inatividade. Este guia aborda estratégias práticas de replicação para PostgreSQL e MySQL.
Conceitos de Replicação
Tipos de Replicação
Replicação Física: Copia os bytes exatos da base de dados. É rápida, mas as réplicas têm de ser versões idênticas do PostgreSQL.
Replicação Lógica: Copia alterações lógicas (operações SQL). É mais flexível, permite versões diferentes e replicação seletiva.
Síncrona vs. Assíncrona:
- Síncrona: O primário aguarda a confirmação da réplica. Sem perda de dados, mas com maior latência.
- Assíncrona: O primário não aguarda. Melhor desempenho, mas com potencial perda de dados.
Replicação por Streaming do PostgreSQL
Configuração do Servidor Primário
# postgresql.conf no primário
# Ativar o arquivamento de WAL
wal_level = replica
max_wal_senders = 10
wal_keep_size = 1GB
# Para replicação síncrona (opcional)
synchronous_standby_names = 'replica1'
# pg_hba.conf — Permitir ligações de replicação
host replication replicator 192.168.1.0/24 md5
Criar utilizador de replicação:
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'secure_password';
Configuração do Servidor Réplica
# Parar o PostgreSQL na réplica
sudo systemctl stop postgresql
# Remover dados existentes
rm -rf /var/lib/postgresql/14/main/*
# Copiar do primário usando pg_basebackup
pg_basebackup -h primary.example.com -U replicator -D /var/lib/postgresql/14/main -P -R
# A flag -R cria standby.signal e configura a ligação
# postgresql.conf na réplica
# Ligação ao primário
primary_conninfo = 'host=primary.example.com port=5432 user=replicator password=secure_password'
# Iniciar a réplica
sudo systemctl start postgresql
Verificar Replicação
-- No primário: verificar o estado da replicação
SELECT client_addr, state, sent_lsn, write_lsn, replay_lsn
FROM pg_stat_replication;
-- Na réplica: verificar o estado de recuperação
SELECT pg_is_in_recovery();
SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();
Replicação Lógica do PostgreSQL
Publisher (Origem)
# postgresql.conf
wal_level = logical
max_replication_slots = 4
max_wal_senders = 4
-- Criar publicação
CREATE PUBLICATION my_publication FOR TABLE users, orders;
-- Ou todas as tabelas
CREATE PUBLICATION full_publication FOR ALL TABLES;
Subscriber (Destino)
-- Criar subscrição
CREATE SUBSCRIPTION my_subscription
CONNECTION 'host=publisher.example.com dbname=mydb user=replicator password=secure'
PUBLICATION my_publication;
-- Verificar o estado
SELECT * FROM pg_stat_subscription;
Replicação MySQL
Configuração do Primário
# my.cnf no primário
[mysqld]
server-id = 1
log_bin = mysql-bin
binlog_format = ROW
binlog_do_db = mydb
-- Criar utilizador de replicação
CREATE USER 'replicator'@'%' IDENTIFIED BY 'secure_password';
GRANT REPLICATION SLAVE ON *.* TO 'replicator'@'%';
FLUSH PRIVILEGES;
-- Obter a posição do binary log
SHOW MASTER STATUS;
-- Nota: valores de File e Position
Configuração da Réplica
# my.cnf na réplica
[mysqld]
server-id = 2
relay_log = mysql-relay-bin
read_only = 1
-- Configurar a replicação
CHANGE MASTER TO
MASTER_HOST='primary.example.com',
MASTER_USER='replicator',
MASTER_PASSWORD='secure_password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
-- Iniciar a replicação
START SLAVE;
-- Verificar o estado
SHOW SLAVE STATUS\G
Estratégias de Failover
Failover Manual (PostgreSQL)
-- Na réplica: promover a primário
SELECT pg_promote();
-- Ou via linha de comandos
pg_ctl promote -D /var/lib/postgresql/14/main
Atualize as strings de ligação da aplicação para apontarem para o novo primário.
Failover Automático com Patroni
O Patroni gere a alta disponibilidade do PostgreSQL com failover automático.
# patroni.yml
scope: postgres-cluster
name: node1
restapi:
listen: 0.0.0.0:8008
connect_address: node1.example.com:8008
etcd:
hosts: etcd1:2379,etcd2:2379,etcd3:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
parameters:
max_connections: 100
postgresql:
listen: 0.0.0.0:5432
connect_address: node1.example.com:5432
data_dir: /var/lib/postgresql/14/main
authentication:
replication:
username: replicator
password: secure_password
superuser:
username: postgres
password: postgres_password
HAProxy para Encaminhamento de Ligações
# haproxy.cfg
frontend postgres_frontend
bind *:5432
default_backend postgres_backend
backend postgres_backend
option httpchk GET /master
http-check expect status 200
server node1 node1:5432 check port 8008
server node2 node2:5432 check port 8008
server node3 node3:5432 check port 8008
Escalabilidade de Leituras com Réplicas
Separação de Leitura/Escrita ao Nível da Aplicação
// Exemplo em Laravel
// config/database.php
'pgsql' => [
'read' => [
'host' => [
'replica1.example.com',
'replica2.example.com',
],
],
'write' => [
'host' => 'primary.example.com',
],
'driver' => 'pgsql',
'database' => 'mydb',
// ...
],
// Forçar ligação de escrita para leituras críticas
$user = DB::connection('pgsql')->select('SELECT * FROM users WHERE id = ?', [1]);
Pooling de Ligações com Réplicas de Leitura
# PgBouncer com vários backends
[databases]
mydb = host=primary.example.com port=5432
mydb_ro = host=replica1.example.com,replica2.example.com port=5432
Monitorização da Replicação
Atraso de Replicação no PostgreSQL
-- No primário: verificar o atraso por réplica
SELECT client_addr,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) / 1024 / 1024 AS lag_mb
FROM pg_stat_replication;
-- Na réplica: verificar o atraso
SELECT EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp())) AS lag_seconds;
Atraso de Replicação no MySQL
SHOW SLAVE STATUS\G
-- Procurar: Seconds_Behind_Master
Limiares de Alertas
- Aviso: Atraso > 10 segundos
- Crítico: Atraso > 60 segundos
- Emergência: Réplica desligada
Backups com Réplicas
Faça backups a partir das réplicas para evitar impactar o primário:
# PostgreSQL — backup a partir da réplica
pg_dump -h replica.example.com -U postgres mydb > backup.sql
# Ou backup físico
pg_basebackup -h replica.example.com -U replicator -D /backup -P
Boas Práticas
- Use replicação síncrona para dados críticos (pelo menos uma réplica)
- Monitorize o atraso de replicação continuamente
- Teste o failover regularmente em ambientes não produtivos
- Mantenha réplicas em diferentes zonas de disponibilidade
- Documente os procedimentos de failover
- Automatize o failover sempre que possível (Patroni, orchestrator)
- Use pooling de ligações para gerir ligações de forma eficiente
Conclusão
A replicação de base de dados fornece a base para alta disponibilidade e recuperação de desastre. Comece com replicação por streaming assíncrona para escalabilidade de leituras, adicione replicação síncrona para dados críticos e implemente failover automático para sistemas de produção. Testes regulares garantem que os seus procedimentos de failover funcionam quando necessário.