Pular para o conteúdo

Incidente · Sênior

GitHub 2012: failover promove réplica atrasada

Incidente real. Pontos centrais: Algoritmos de Consenso, Padrões de Disponibilidade e Padrões de Consistência.

14 min de leitura · Incidente em 2012, durou · Fonte: GitHub · Conteúdo revisado em 23 de outubro de 2026

Resposta curta

Incidente real. Pontos centrais: Algoritmos de Consenso, Padrões de Disponibilidade e Padrões de Consistência. O post de disponibilidade que o GitHub publicou em setembro de 2012 é a fonte deste caso. Ele descreve duas quedas no início da mesma semana e aponta o failover automático do banco de produção principal como a causa raiz das duas.

01 · CONTEXTO

Um cluster novo que troca de primário sozinho

O post de disponibilidade que o GitHub publicou em setembro de 2012 é a fonte deste caso. Ele descreve duas quedas no início da mesma semana e aponta o failover automático do banco de produção principal como a causa raiz das duas.

Em meados de agosto, a operação substituiu um par de servidores MySQL baseados em DRBD por um cluster de três nós. O cluster apresenta à aplicação dois IPs virtuais, um de leitura e escrita e outro somente leitura, gerenciados por Pacemaker e Heartbeat. O Percona Replication Manager coordena a replicação e move entre os nós os papéis de ativo (o mestre que aceita leitura e escrita) e de standby (réplica somente leitura).

Segundo o post, o novo desenho dava failovers mais eficientes. Na arquitetura anterior, trocar de banco exigia a partida a frio do MySQL; no cluster novo o MySQL roda em todos os nós o tempo todo, e o failover apenas move o IP virtual depois de descarregar as transações e ajustar a variável read_only.

  1. A aplicação fala com o banco pelo IP virtual de leitura e escrita, que aponta para o nó em papel ativo.

    Diagrama da arquitetura: Cluster MySQL com Pacemaker e Percona Replication Manager
    CPAplicação
    NWIP virtual de leitura e escrita
    DBNó ativoativo
    DBNó standby
    DBTerceiro nó
    NWPacemaker e Percona Replication Manager
  2. O nó standby é uma réplica somente leitura do nó ativo.

    Diagrama da arquitetura: Cluster MySQL com Pacemaker e Percona Replication Manager
    CPAplicação
    NWIP virtual de leitura e escrita
    DBNó ativo
    DBNó standbystandby
    DBTerceiro nó
    NWPacemaker e Percona Replication Manager
  3. O gerenciador do cluster faz os health checks e move o IP virtual e os papéis entre os nós.

    Diagrama da arquitetura: Cluster MySQL com Pacemaker e Percona Replication Manager
    CPAplicação
    NWIP virtual de leitura e escrita
    DBNó ativo
    DBNó standby
    DBTerceiro nó
    NWPacemaker e Percona Replication Managerdecide o failover
  4. Como o MySQL já roda em todos os nós, o failover se resume a mover o IP virtual, sem partida a frio.

    Diagrama da arquitetura: Cluster MySQL com Pacemaker e Percona Replication Manager
    CPAplicação
    NWIP virtual de leitura e escritasó o IP se move
    DBNó ativo
    DBNó standby
    DBTerceiro nó
    NWPacemaker e Percona Replication Manager

02 · SEGUNDA-FEIRA

Dois failovers que ninguém queria

A origem foi uma migração de banco que gerou mais carga do que a operação já tinha visto nesse tipo de migração. A carga foi tanta que os health checks do Percona Replication Manager falharam no mestre.

Em resposta, o gerenciador moveu o papel ativo para outro servidor do cluster e parou o MySQL no nó que julgou falho. O banco escolhido tinha o buffer pool do InnoDB frio e teve desempenho ruim; a carga de consultas do site sobre esse cache frio logo fez os health checks falharem de novo, e o papel ativo voltou ao servidor de origem.

  1. Com a carga da migração, os health checks do gerenciador falham no nó ativo.

    Diagrama da arquitetura: Failover para um nó com buffer pool frio
    CPAplicação
    NWIP virtual de leitura e escrita
    NWPercona Replication Manager
    DBNó ativo originalhealth check falhou
    DBNó escolhido
  2. O gerenciador move o papel ativo para outro servidor e para o MySQL no nó que julgou falho.

    Diagrama da arquitetura: Failover para um nó com buffer pool frio
    CPAplicação
    NWIP virtual de leitura e escrita
    NWPercona Replication Manager
    DBNó ativo originalMySQL parado
    DBNó escolhidonovo ativo
  3. O nó escolhido tem o buffer pool do InnoDB frio e responde mal à carga de consultas do site.

    Diagrama da arquitetura: Failover para um nó com buffer pool frio
    CPAplicação
    NWIP virtual de leitura e escrita
    NWPercona Replication Manager
    DBNó ativo original
    DBNó escolhidobuffer pool frio
  4. Os health checks falham de novo e o papel ativo volta ao servidor em que estava.

    Diagrama da arquitetura: Failover para um nó com buffer pool frio
    CPAplicação
    NWIP virtual de leitura e escrita
    NWPercona Replication Manager
    DBNó ativo originalpapel de volta
    DBNó escolhidohealth check falhou
  5. O autor do post liga o maintenance-mode, em que o gerenciador não faz health checks nem failover automático.

    Diagrama da arquitetura: Failover para um nó com buffer pool frio
    CPAplicação
    NWIP virtual de leitura e escrita
    NWPercona Replication Managermaintenance-mode
    DBNó ativo original
    DBNó escolhido

O desempenho do site se recuperou aos poucos, conforme o buffer pool atingiu níveis normais.

03 · TERÇA-FEIRA

A partição e a eleição do nó atrasado

Na manhã seguinte, um desenvolvedor avisou a operação de resultados de consulta incorretos vindos do nó em papel de standby. A investigação concluiu que o maintenance-mode do dia anterior tinha impedido ações que fariam o nó eleito standby trocar de mestre de replicação e começar a replicar.

Ao tentar desativar o maintenance-mode, ocorreu um segfault do Pacemaker que resultou em uma partição do estado do cluster. Dois nós, chamados a e b, rejeitavam a maior parte das mensagens do terceiro, c, enquanto c rejeitava a maior parte das mensagens dos outros dois.

No primeiro cluster, a eleição foi interrompida por mensagens do segundo e o MySQL foi parado. No segundo, de um único nó, o nó c foi eleito e as mensagens posteriores do cluster de dois nós foram descartadas. O nó c era justamente o que a operação já havia determinado estar desatualizado.

A equipe detectou o problema e desligou o nó desatualizado, para encerrar a partição e evitar mais divergência de dados. Com isso, todo o acesso ao banco de produção, e portanto ao github.com, ficou fora do ar.

  1. Os três nós trocam mensagens de cluster, e o cluster exige acordo da maioria antes de agir.

    Diagrama da arquitetura: Partição do cluster e eleição do nó atrasado
    DBNó a
    DBNó b
    DBNó c
  2. Um segfault do Pacemaker particiona o cluster: a e b rejeitam a maior parte das mensagens de c, e c rejeita as deles.

    Diagrama da arquitetura: Partição do cluster e eleição do nó atrasado
    DBNó a
    DBNó b
    DBNó cpartição
  3. No cluster de a e b, a eleição de mestre é interrompida por mensagens do outro lado e o MySQL é parado.

    Diagrama da arquitetura: Partição do cluster e eleição do nó atrasado
    DBNó aMySQL parado
    DBNó bMySQL parado
    DBNó c
  4. No cluster de um nó só, c é eleito, e c era o nó que a operação já havia determinado estar desatualizado.

    Diagrama da arquitetura: Partição do cluster e eleição do nó atrasado
    DBNó a
    DBNó b
    DBNó celeito e desatualizado
  5. A equipe desliga o nó desatualizado para encerrar a partição, e todo o acesso ao banco de produção cai.

    Diagrama da arquitetura: Partição do cluster e eleição do nó atrasado
    DBNó a
    DBNó b
    DBNó cdesligado

04 · O ESTRAGO

Dados fora de sincronia entre armazenamentos

A divergência de dados tornou possíveis inconsistências entre o MySQL e outros armazenamentos. O GitHub usa Redis para consultar entradas do feed do painel e rotas de repositório a partir de ids gerados automaticamente pelo MySQL; para registros criados na janela, as relações entre os dois armazenamentos saíram de sincronia.

Efeito descrito pela fonteContexto
PainéisAlguns eventos criados na janela apareceram nos painéis de usuários erradosO Redis é consultado com ids gerados pelo MySQL
RoteamentoAlguns repositórios criados na janela foram roteados incorretamenteAs relações entre os armazenamentos saíram de sincronia
Repositórios privadosDezesseis repositórios privados ficaram acessíveis a quem não era colaborador ou da equipePor sete minutos, segundo o post

05 · A DECISÃO

Failover só quando a operação manda

O post afirma que, se alguém da operação fosse consultado sobre se o failover deveria ter ocorrido, a resposta seria um não categórico. Ele ressalva que há muitas situações em que o failover automático é uma ótima estratégia de disponibilidade, mas conclui que a disponibilidade do banco primário de produção não é uma delas.

Por isso, a configuração do Pacemaker foi alterada para que o failover do papel ativo só ocorra quando iniciado por um membro da operação. A empresa também investiga formas de que failovers inevitáveis não prejudiquem o desempenho, incluindo mecanismos para aquecer o buffer pool dos bancos escravos, e faz uma auditoria da pilha Pacemaker e Heartbeat.

  1. O failover do papel ativo passa a depender de um membro da operação, e o gerenciador não o inicia sozinho.

    Diagrama da arquitetura: Failover do papel ativo iniciado pela operação
    CLEquipe de operaçõesdecide
    NWPacemaker
    NWIP virtual de leitura e escrita
    DBNó ativo
    DBNó standby
  2. Para failovers inevitáveis, a empresa investiga formas de aquecer o buffer pool dos bancos escravos.

    Diagrama da arquitetura: Failover do papel ativo iniciado pela operação
    CLEquipe de operações
    NWPacemaker
    NWIP virtual de leitura e escrita
    DBNó ativo
    DBNó standbyaquecer em estudo
  3. A pilha Pacemaker e Heartbeat passa por uma auditoria focada no caminho de código que disparou o segfault.

    Diagrama da arquitetura: Failover do papel ativo iniciado pela operação
    CLEquipe de operações
    NWPacemakerem auditoria
    NWIP virtual de leitura e escrita
    DBNó ativo
    DBNó standby

Perguntas frequentes

O que é GitHub 2012: failover promove réplica atrasada?

Incidente real. Pontos centrais: Algoritmos de Consenso, Padrões de Disponibilidade e Padrões de Consistência.

O que o design de GitHub 2012: failover promove réplica atrasada cobre?

Ele está organizado nestas seções: Um cluster novo que troca de primário sozinho, Dois failovers que ninguém queria, A partição e a eleição do nó atrasado, Dados fora de sincronia entre armazenamentos e Failover só quando a operação manda.

Quanto tempo leva GitHub 2012: failover promove réplica atrasada e qual é o nível?

Leva cerca de 14 minutos para ler e tem nível Sênior.

Agora projete você mesmo

Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.