DevGuideTK
← Trilha Backend

Replicação

Cópias do banco para leitura e para tolerar falhas, e o atraso entre a principal e as réplicas.

As decisões de replicação são cinco: síncrona ou assíncrona, quantas réplicas e onde, como trocar de principal, como rotear as leituras e o que monitorar.

Síncrona ou assíncrona

AssíncronaSíncrona com uma réplicaSíncrona com quórum (ANY 1 de 2 ou mais)
Custo por COMMITNenhumUma ida e volta até a réplica (6,5 contra 18,3 ms no teste)Uma ida e volta até a réplica mais rápida
Perda numa troca de principalO que não foi enviado (no teste, 1.000 gravações confirmadas)NenhumaNenhuma
Se uma réplica cairNada mudaAs gravações travamNada muda, se outra responder
Bom paraA maioria dos sistemasRaramente: o risco de travar é altoDados que não podem se perder: pagamentos, saldos

A replicação síncrona com uma única réplica é a pior combinação: junta o custo do síncrono com a fragilidade de depender de uma máquina. No teste, uma réplica síncrona fora do ar deixou um INSERT parado por tempo indeterminado, sem respeitar o statement_timeout.

O synchronous_commit pode ser ajustado por transação. Um sistema assíncrono pode exigir confirmação síncrona só nas gravações críticas (SET LOCAL synchronous_commit = remote_write), e o contrário também vale.

Quantas réplicas e onde

TopologiaProtege contraCusto
Uma réplica na mesma zonaFalha do servidorBaixo
Réplica em outra zona da mesma regiãoFalha de uma zona da nuvemPouca latência a mais
Réplica em outra regiãoDesastre regionalLatência alta: síncrona fica cara demais; assíncrona perde mais numa troca
Réplicas em cascata (réplica de réplica)Carga de envio no principalMais atraso nas réplicas da ponta
Réplica com atraso proposital (recovery_min_apply_delay)Um DELETE errado: a réplica ainda tem os dados por algumas horasNão serve para leitura nem para troca rápida

Uma combinação comum: uma réplica síncrona em quórum na mesma região para não perder dados, e uma assíncrona em outra região para desastres.

Como trocar de principal

FormaComo funcionaCuidados
ManualAlguém promove a réplica (pg_promote()) e aponta a aplicação para elaLento, e às três da manhã
Automática, com um gerenciador (Patroni, repmgr, pg_auto_failover)O gerenciador detecta a falha, escolhe a réplica e a promovePrecisa de um consenso externo (etcd, Consul) para não promover duas
Banco gerenciado (RDS, Cloud SQL, Azure)O serviço faz a troca e mantém o mesmo endereçoConfira o tempo de troca e o que se perde no modo escolhido

O risco principal de uma troca é o cérebro dividido (split brain): o principal antigo volta e continua aceitando gravações, e agora há dois. Os gerenciadores impedem isso com um líder eleito por consenso e isolando o antigo antes de promover o novo.

E a aplicação precisa achar o principal novo: um endereço que acompanha a troca (DNS, proxy, ou uma lista de servidores na string de conexão com target_session_attrs=read-write), e reconexão automática no pool.

Como rotear as leituras

FormaComo funcionaQuando usar
Tudo no principalRéplicas só para tolerar falhasO padrão, até o principal ficar sobrecarregado
Leituras separadas por tipoRelatórios, buscas e listagens na réplica; o resto no principalA maioria dos sistemas com réplicas de leitura
Ler o que gravouDepois de gravar, a leitura vai para o principal, ou para uma réplica que já aplicou o LSN da gravaçãoTelas que mostram o que o usuário acabou de alterar
Afinidade por tempoPor alguns segundos depois de gravar, o usuário lê do principalSimples, sem LSN; o tempo é um chute
Síncrono com remote_applyA réplica já aplicou quando o COMMIT voltaQuando toda leitura na réplica precisa ver as gravações confirmadas

O "ler o que gravou" com LSN é o mais preciso: a aplicação guarda o LSN da última gravação do usuário (na sessão, num cookie) e só lê de uma réplica que já passou dele. A Implementação mostra isso nas cinco linguagens, e um erro que o teste encontrou: o LSN precisa ser lido depois da confirmação.

Decisões que dependem do valor exato (saldo, estoque, permissões) leem do principal, sempre.

O que monitorar

MétricaOndePor quê
Atraso de replicação, em bytes e em tempopg_stat_replication no principal, pg_last_xact_replay_timestamp() na réplicaQuanto as leituras estão atrasadas, e quanto se perde numa troca
Slots e WAL retidopg_replication_slotsNo teste, um slot abandonado reteve 2,5 GB
Estado das réplicas síncronassync_state em pg_stat_replicationUma síncrona fora trava as gravações
Sessões esperando a réplicawait_event = 'SyncRep' em pg_stat_activityO sinal de que as gravações estão paradas

E configure max_slot_wal_keep_size: ele troca a queda do principal por disco cheio pela perda de uma réplica, que é recuperável.

Resumo da decisão

  1. Assíncrona para a maioria; síncrona com quórum para dados que não podem se perder, nunca com uma única réplica.
  2. Réplicas em outra zona, e uma em outra região para desastres.
  3. Troca automática com consenso, ou um banco gerenciado, e a aplicação reconectando no principal novo.
  4. Leituras na réplica só onde o atraso é aceitável, com "ler o que gravou" por LSN nas telas que precisam.
  5. Monitorar atraso, slots e esperas, com max_slot_wal_keep_size configurado.

O próximo nível mostra o roteamento com LSN nas cinco linguagens e a configuração testada.

Prompts para aprofundar

Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.

  • Planejar a replicação do meu banco

    Quero planejar a replicação do banco do meu sistema.
    
    Pergunte qual banco e onde ele roda, quanto de dado eu aceito perder numa falha, quanto tempo o sistema pode ficar fora, o volume de leituras e gravações e se o banco é gerenciado.
    
    Proponha:
    1. O modo de replicação e quantas réplicas, e onde.
    2. Como a troca de principal acontece.
    3. Quais leituras vão para as réplicas.
    4. O que monitorar e os alertas.
    5. Como testar uma troca de principal antes de precisar dela.
  • Separar leituras e gravações na aplicação

    Quero que a minha aplicação mande as leituras para as réplicas.
    
    Pergunte qual linguagem, framework e ORM eu uso, e quais telas e rotas existem.
    
    Me ajude a:
    1. Configurar as conexões com o principal e as réplicas.
    2. Classificar as leituras: quais aceitam atraso e quais não.
    3. Implementar "ler o que gravou" para as telas que precisam.
    4. Lidar com uma réplica fora do ar ou muito atrasada.
    5. Testar com a réplica pausada.
  • Ensaiar uma troca de principal

    Quero ensaiar uma troca de principal antes que ela aconteça de verdade.
    
    Pergunte qual banco, como a replicação está configurada e como a aplicação se conecta.
    
    Monte comigo o roteiro do ensaio: o que medir antes, como provocar a falha, o que observar na aplicação, como confirmar que nada se perdeu (ou quanto se perdeu) e como voltar ao estado normal. No final, liste o que precisa mudar se o ensaio mostrar problemas.