Pular para o conteúdo

Alta disponibilidade em banco de dados

Avançado18 min de leituradados

Alta disponibilidade em banco não é “ligar a réplica”. É escolher, conscientemente, o que você aceita perder quando algo falha: latência de escrita, dado recente ou disponibilidade. Não existe configuração que evite os três — e quem não escolhe descobre a escolha durante o incidente.

Antes de tudo, separe os conceitos que costumam ser confundidos: HA protege de falha de instância ou de zona; backup protege de erro humano e corrupção; DR protege de perda de região. Réplica não é backup: um DELETE errado replica em milissegundos.

  • Assíncrona: o primário confirma o commit sem esperar a réplica. Escrita rápida, mas um failover pode perder as últimas transações (perda em janela de segundos).
  • Síncrona: o commit só confirma depois que a réplica gravou. Nada se perde no failover, e cada escrita paga o custo da rede — o que entre zonas é aceitável e entre regiões, raramente.
-- Postgres: síncrono para uma réplica, assíncrono para as demais
ALTER SYSTEM SET synchronous_standby_names = 'ANY 1 (replica_a, replica_b)';
SELECT client_addr, state, sync_state,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS atraso_bytes
FROM pg_stat_replication; -- monitore este atraso como métrica de primeira classe

O arranjo mais comum e equilibrado: síncrono com uma réplica na outra zona da mesma região (isso é o “Multi-AZ” dos serviços gerenciados) e assíncrono para réplicas de leitura e para outra região.

Failover automático troca uma indisponibilidade longa por um risco: dois nós se acharem primários ao mesmo tempo — split-brain — e aceitarem escritas divergentes. Reconciliar isso depois é, na prática, escolher qual conjunto de dados descartar.

Os mecanismos que evitam isso:

  • Quórum: um número ímpar de nós observadores decide quem promove (Patroni com etcd, por exemplo). Dois nós sozinhos não conseguem decidir com segurança.
  • Fencing / STONITH: o nó antigo é isolado (ou desligado) antes da promoção.
  • Ponto único de entrada: a aplicação fala com um endereço que o mecanismo de failover reaponta, e não com o IP do primário.

Se você usa banco gerenciado (RDS, Cloud SQL, Azure Database), isso vem resolvido — e é o principal motivo para preferir gerenciado a operar cluster próprio, a menos que exista razão forte.

Independente do mecanismo: teste o failover. Um failover que nunca foi exercitado é uma hipótese. Faça em janela combinada, meça o tempo real de indisponibilidade e observe o comportamento da aplicação — muitas aplicações não reconectam sozinhas.

Réplica de leitura escala consulta, não escrita, e traz um efeito que quebra aplicação: a leitura pode devolver dado mais antigo do que a escrita que acabou de acontecer.

usuário salva o perfil → primário
usuário recarrega a tela → réplica (300 ms atrás) → "cadê minha alteração?"

Padrões que resolvem: leia do primário logo após escrever (read-your-writes), use a réplica só para relatório e listagem tolerante a atraso, e monitore o atraso de replicação com alerta — acima de um limite, tire a réplica do balanceamento.

Nunca use réplica atrasada para decisão que depende de consistência: saldo, estoque, autorização.

Banco tem limite pequeno de conexões e cada uma custa memória. Aplicação em container multiplica: 20 réplicas × 20 conexões = 400 conexões, e o banco aceita 200.

Use um pooler (PgBouncer, ProxySQL, RDS Proxy) em modo transação e dimensione com a conta explícita: réplicas × pool_por_réplica ≤ limite − reserva para manutenção.

pgbouncer.ini
pool_mode = transaction # prepared statements e advisory locks exigem atenção aqui
max_client_conn = 2000
default_pool_size = 25

Esgotamento de pool é um dos incidentes mais comuns e mais disfarçados: a aplicação fica lenta, o banco parece ocioso, e a causa é fila esperando conexão. Meça conexões_em_uso / pool_size e alerte acima de 80%.

Diante de uma partição de rede, você escolhe entre consistência e disponibilidade. A tradução operacional:

  • Escolher consistência: em dúvida, o banco recusa escrita. Você fica indisponível por um período, mas nunca com dado divergente. É o certo para dinheiro e estoque.
  • Escolher disponibilidade: o sistema aceita escrita nos dois lados e reconcilia depois. É aceitável para carrinho, contador, log de eventos e cache.

Escolha por sistema, e escreva a decisão junto do serviço. A pergunta que revela a resposta certa: se ficarmos indisponíveis por 5 minutos, o prejuízo é maior ou menor que ter dois valores conflitantes para o mesmo registro?

Próximo passo: HA cobre falha de instância e de zona. Para perda de região, siga para Recuperação de desastre.