Caso de descoberta de uma condição de corrida no Aurora RDS
(hightouch.com)- Caso em que um bug de condição de corrida ocorrido no AWS Aurora RDS foi confirmado experimentalmente, com a AWS validando a causa
- A Hightouch, durante a expansão do sistema de processamento de eventos, descobriu que no processo de failover do Aurora ocorria uma falha na troca da instância de escrita
- A análise dos logs confirmou que duas instâncias executaram operações de escrita ao mesmo tempo, causando conflito na camada de armazenamento e encerramento de processos
- A AWS confirmou oficialmente que a causa foi a promoção de um novo writer antes da conclusão do rebaixamento do writer anterior, devido a um problema no processamento de sinais internos
- Este caso destaca a importância do controle de concorrência em sistemas distribuídos de grande escala e a necessidade de interromper escritas durante o failover
Contexto
- Em 20 de outubro de 2025, ocorreu uma falha na região
us-east-1da AWS causada por um bug de condição de corrida no sistema de gerenciamento de DNS - Por causa disso, a Hightouch viu o backlog de processamento de eventos disparar, chegando ao limite do sistema
- Para garantir capacidade de processamento, em 23 de outubro foi feito um upgrade das instâncias Aurora RDS e, nesse processo, foi descoberto um novo bug de condição de corrida
Estrutura do sistema de eventos da Hightouch
- O sistema responsável pela coleta e entrega de eventos é composto por Kubernetes, Kafka e Postgres (Aurora)
- O Postgres é usado como fila de metadados em lote e processa 500 mil eventos por segundo em menos de 1 segundo
- O Aurora PostgreSQL é composto por uma instância somente de escrita (primary), instâncias somente de leitura (replica) e uma camada de armazenamento compartilhada
Plano de upgrade
- Adicionar uma instância de leitura → fazer upgrade do reader existente e atribuir prioridade de failover → executar o failover → fazer upgrade do writer existente → remover o reader temporário
- Esse procedimento é o método descrito na documentação da AWS e já havia sido validado por testes de carga em ambiente de staging
Tentativa de upgrade e surgimento do problema
- Em 23 de outubro, às 16:39 EDT, após a execução do failover, ocorreu o fenômeno em que o writer anterior retornou novamente como primary
- Nas duas tentativas, o resultado foi o mesmo, e alguns serviços passaram a apresentar erro de impossibilidade de escrita (DatabaseError: cannot execute UPDATE in a read-only transaction)
- A análise dos logs confirmou registros de que duas instâncias executaram operações de escrita simultaneamente e foram encerradas por conflito de armazenamento
Causa da condição de corrida
- Durante o processo de failover do Aurora, surgiu uma condição de corrida entre a etapa 3 (rebaixamento do writer anterior) e a etapa 4 (promoção do novo writer)
- Com isso, as duas instâncias passaram a ter permissão de escrita ao mesmo tempo, gerando conflito
- Quando a nova tentativa foi feita com o tráfego de escrita removido, o failover foi concluído normalmente, comprovando a hipótese da condição de corrida
Confirmação e resposta da AWS
- Após revisão interna, a AWS confirmou que a causa era um erro no processamento do sinal de rebaixamento do writer, sem relação com a configuração da Hightouch nem com o padrão de tráfego
- A correção está incluída no roadmap, e a recomendação temporária é interromper as escritas durante o failover
Medidas finais
- A Hightouch concluiu o upgrade do cluster e
- adicionou um procedimento de interrupção de escrita antes de failovers intencionais
- reforçou o monitoramento da mudança de papel do writer
- atualizou o manual operacional (playbook)
Principais lições
- É necessário preparar recuperação para transições de estado inesperadas durante migrações
- Garantir observabilidade é essencial para detectar problemas
- É importante projetar para minimizar o impacto entre componentes de sistemas distribuídos
- É preciso reconhecer a diferença entre ambiente de teste e ambiente de produção
Não há informações adicionais no texto original
1 comentários
Comentários no Hacker News
Ao ler este texto, parece que durante um failover manual a aplicação sempre falha se tentar manter o tráfego de escrita normalmente
Mas isso levanta algumas dúvidas. Fico me perguntando por que outros usuários do Aurora não enfrentam esse problema o tempo todo, como a AWS não saberia disso e, se souber, por que não trataria isso como um incidente crítico de nível P0
Talvez haja alguma condição sutil, como o estado de transações em andamento ou timeouts, influenciando o comportamento
SELECT ... FOR UPDATEfalhava silenciosamente e a transação mudava para o modo autocommit. Ninguém ligou e eu fiquei falando disso sozinho, mas alguns meses depois outra pessoa entrou em contato dizendo que tinha passado pelo mesmo problema. No fim isso foi corrigido, mas eu já tinha perdido o interesseLink relacionado: pergunta no Stack Overflow
Já vi comportamentos inesperados várias vezes no Aurora PostgreSQL
Em especial, durante o Zero Downtime Patching (ZDP), o estado da sessão era mantido de forma incorreta, fazendo até consultas simples serem canceladas muito antes do
statement_timeoutMeu palpite é que, quando o cliente se reconecta, o Aurora herda o estado antigo de temporizadores da sessão anterior, e por isso a consulta é cancelada imediatamente
Nós também fazemos failover regularmente em um ambiente com tráfego de escrita muito alto, mas operamos isso de forma estável com um processo automatizado usando o AWS JDBC wrapper
É surpreendente ver um problema desses quando se paga justamente acreditando que o Aurora vai manter esse tipo de invariância básica
Pelos logs e pela explicação da AWS, parece que a hipótese do autor original está errada
Parece que, depois da falha na promoção, um processo externo de monitoramento detectou a inconsistência no estado do cluster e encerrou o processo à força com kill -9. As mensagens relacionadas ao subsistema de armazenamento vieram depois disso
Gostaria de perguntar sobre a comparação de desempenho entre Aurora e RDS Postgres
Se não houver necessidade de Multi-AZ ou failover rápido, seria possível obter desempenho melhor no RDS com uma configuração gp3 64k IOPS? O Aurora parece ter desempenho fraco de insert e custo alto. Também é difícil confiar nos benchmarks, porque muitos nem deixam clara a configuração usada no RDS
Além disso, não é preciso provisionar IOPS manualmente, e ele oferece cerca de 80k IOPS.
Também há dois modelos de cobrança de IO: o pay-per-IO é melhor para cargas leves, enquanto o modo de tarifa fixa é vantajoso para workloads com muito IO.
E, só para constar, o Serverless quase sempre foi antieconômico. Só vale a pena quando há picos curtos de uso
Isso mostra bem o “modelo de blocos de Lego” de que os engenheiros da AWS falam
A camada de armazenamento foi projetada de forma totalmente independente, então mesmo quando o serviço de cima falhou, a consistência dos dados foi preservada. Acho que é um bom exemplo da engenharia da AWS
Foi dito que a AWS recomendou “parar as escritas durante o failover”, e fiquei curioso se seria possível compartilhar o número do caso relacionado
Fico aliviado em saber que não fui o único a passar por esse problema
A arquitetura do Aurora de separação entre computação e armazenamento é interessante
O Hyperscale do MSSQL tem uma estrutura parecida, e é praticamente o único produto da Azure que eu realmente consideraria usar