IL-0310 Hightouch · 2025-10-23databaseaws
Aurora PostgreSQL 의 수동 장애 조치가 스스로 되돌아가 원래 writer 가 남고 백엔드의 쓰기 쿼리가 실패했다
Hightouch Events 는 이벤트 처리에 Kafka 를 쓰고, 배치 메타데이터를 담는 큐 저장소로 Amazon Aurora PostgreSQL 을 쓴다. 10월 20일 us-east-1 AWS 장애 뒤 밀린 이벤트를 처리하면서 작은 Postgres 인스턴스가 한계에 몰렸고, 팀은 여유를 늘리려고 데이터베이스 크기를 키우기로 했다. Aurora 는 크기를 키울 때 장애 조치가 빨리 끝나므로, 팀은 10월 23일 이 작업을 예약된 점검 시간 없이 진행했다. 계획은 임시 reader 인 instance #3 을 더하고, 기존 reader 인 instance #2 를 목표 크기로 키워 장애 조치 우선순위를 가장 높게 준 뒤, 장애 조치로 instance #2 를 writer 로 올리는 것이었다. 예상 중단 시간은 15초 미만이었고, 같은 날 스테이징의 부하 시험에서는 이 절차가 문제없이 끝났다.
16:39 EDT 와 16:43 에 실행한 장애 조치는 두 번 모두 잠깐 승격됐다가 되돌아갔고, 원래 writer 인 instance #1 이 primary 로 남았다. AWS 에서는 클러스터가 정상으로 보였지만 백엔드 서비스는 read-only transaction 오류로 쓰기를 하지 못했고, 팀은 서비스를 재시작해 정상으로 돌렸다. 데이터베이스 로그에서는 두 인스턴스 모두 쓰기 쿼리를 처리하던 프로세스가 signal 9 로 죽고 storage runtime process crash 로 내려간 기록이 나왔다. 팀은 장애 조치 동안 Aurora 가 잠깐 두 인스턴스 모두에 쓰기를 허용했고, 분산 저장 계층이 동시 쓰기를 거부해 두 인스턴스가 모두 죽었다는 가설을 세웠다. 팀은 이것을 원래 writer 를 강등하고 새 writer 를 승격하는 단계와 새 writer 가 쓰기를 받는 단계 사이의 레이스 컨디션으로 보았다.
가설을 확인하려고 데이터베이스에 쓰는 서비스를 모두 스케일 다운한 뒤 장애 조치를 다시 실행했고, 이번에는 성공했다. AWS 는 내부 검토 뒤 근본 원인이 원래 writer 를 강등하는 과정의 내부 신호 문제였고, 그 때문에 장애 조치 뒤에도 writer 가 바뀌지 않았다고 확인했다. AWS 는 Hightouch 의 구성이나 사용 방식에 이 버그를 일으킬 특별한 점은 없었다고 했다. 수정은 AWS 로드맵에 있다. 그 전까지 AWS 가 권고하는 완화책은 장애 조치를 필요할 때만 쓰고 장애 조치 동안 데이터베이스에 쓰기가 실행되지 않게 하는 것이다. Hightouch 는 us-east-1 클러스터의 크기를 키우는 작업을 마쳤다.
- 심각도
- –
- 영향 범위
- Hightouch Events backend services could not run write queries during two failover attempts until they were restarted, and the planned database upsize failed until a controlled failover with all database writers scaled down
- 영향 사용자
- –
- 지역
- us-east-1
- 감지까지
- –
- 복구까지
- –
증상
인스턴스 크기를 키우려고 Aurora 클러스터에서 장애 조치를 실행했다. 새 writer 로 올라가던 instance #2 는 잠깐 승격됐다가 곧 되돌아갔고, 원래 writer 인 instance #1 이 primary 로 남았다. AWS 콘솔에서는 클러스터가 모두 정상으로 보였지만 백엔드 서비스는 쓰기 쿼리를 실행하지 못했다.
일부 파드의 백엔드 애플리케이션 로그에 DatabaseError: cannot execute UPDATE in a read-only transaction 오류가 찍혔다. 서비스를 재시작하자 오류가 사라졌다.
데이터베이스 로그를 받아 보니 승격되던 reader 와 원래 writer 양쪽에 같은 줄이 같은 순서로 찍혀 있었다. LOG: database system is ready to accept connections 가 찍힌 뒤 LOG: server process (PID 799) was terminated by signal 9: Killed 가 나왔고, 죽은 프로세스는 백엔드가 보낸 쓰기 쿼리를 실행하고 있었다. 이어서 FATAL: Can't handle storage runtime process crash 와 LOG: database system is shut down 이 찍혔다.
장애 조치 동안 read replica 인 instance #2 의 연결 수, 네트워크 트래픽, 커밋 처리량이 치솟았다. 앱에서 오는 읽기 쿼리 트래픽은 그대로였으므로, 늘어난 트래픽은 writer 에 연결되어야 할 백엔드 서비스에서 온 것이었다.
16:39 EDT 첫 시도에 이어 16:43 에 다시 장애 조치를 실행했지만 똑같이 잠깐 승격됐다가 바로 되돌아갔다. 5분 사이에 두 번 실패했고, 그동안 코드 변경, 특이한 쿼리, 트래픽 급증은 없었다.
팀은 먼저 절차에 실수가 있었는지 확인하고 같은 문제를 겪은 사례를 인터넷에서 찾았지만 아무것도 나오지 않았다. 같은 날 앞서 스테이징 환경의 부하 시험에서는 같은 절차가 문제없이 끝났다. 백엔드는 writer 를 가리키는 클러스터 엔드포인트로 접속한다. 팀은 세 가지 가능성을 따져 보았다. 클러스터가 연결을 끊지 않아 파드가 writer 변경을 몰랐을 가능성, 클러스터 엔드포인트가 reader 를 잘못 가리켰을 가능성, writer 에 연결됐지만 쓰기가 실행 중에 거부됐을 가능성이다. 팀은 이 가운데 뒤의 두 가지를 강하게 의심했다.
원인
원인 소프트웨어 결함
- 촉발
- 2025-10-20 us-east-1 AWS 장애 뒤 밀린 이벤트를 처리하며 작은 Postgres 인스턴스가 한계에 몰리자, Hightouch 는 10월 23일 예약된 점검 시간 없이 Aurora 인스턴스 크기를 키우는 작업을 했다. 크기를 키운 reader 를 writer 로 올리려고 16:39 EDT 에 장애 조치를 실행했다.
감지
장애 조치를 실행한 뒤 AWS 콘솔 페이지를 새로 고치자 원래 writer 인 instance #1 이 여전히 primary 로 보였고, 백엔드 서비스가 쓰기 쿼리를 실행하지 못했다. 팀은 Datadog 에서 인스턴스마다 쿼리를 지켜보고 있었고 RDS 의 데이터베이스 로그를 받아 볼 수 있었기 때문에, writer 가 잠깐 바뀌었다가 돌아간 것을 찾아낼 수 있었다.
조치
- 백엔드 서비스를 재시작해 쓰기 오류를 없애고 정상 동작을 되찾았다.
- 데이터베이스에 쓰는 서비스를 모두 스케일 다운했다.
- 동시 쓰기가 없는 상태에서 장애 조치를 다시 실행해 성공했고, us-east-1 클러스터의 크기를 키웠다.
후속 조치
- 내부 플레이북에 의도한 장애 조치 전에 쓰기 서비스를 먼저 멈추는 단계를 넣었다.
- writer 로 표시되는 인스턴스가 예상치 않게 바뀌는 것을 잡는 모니터링을 더했다.
교훈
믿을 만한 서비스에서 하는 마이그레이션이라도 목표 상태, 처음 상태, 그 중간 어느 상태로든 끝날 수 있다. 그러므로 트래픽을 다른 곳으로 돌리고 의존 서비스의 짧은 중단을 견딜 준비를 해 둔다. writer 가 잠깐 바뀐 일은 인스턴스별 쿼리 모니터링과 데이터베이스 로그가 있어서 찾을 수 있었다. 큰 분산 시스템에서는 구성 요소 하나가 시스템에 미치는 영향을 격리해 두면 가동 시간과 유지 보수 모두에 도움이 된다. 스테이징의 부하 시험은 운영 환경을 그대로 재현하지 못했고, 이번 레이스 컨디션을 일으킨 조건도 재현하지 못했다.
출처
관련 사례
같은 원인 · 공통 데이터베이스, 데이터베이스 장애 조치 관리자
같은 원인 · 공통 데이터베이스, 데이터베이스 장애 조치 관리자
IL-0451Aurora MySQL 에서 인덱스를 INVISIBLE 로 바꿀 때마다 Reader 3대의 버퍼풀이 무효화돼 CPU 와 ReadIOPS 가 튀었다Daangn · 2026같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0281PostHog US 리전 Logs 제품의 ClickHouse 클러스터가 S3 에 둔 로그 데이터를 거의 다 지워 3일보다 오래된 로그가 사라졌다PostHog · 2026같은 원인 · 공통 데이터베이스
IL-0150DynamoDB DNS 자동화의 경쟁 조건이 us-east-1 리전 엔드포인트의 DNS 레코드를 비워 DynamoDB 와 EC2 인스턴스 시작이 실패했고, 그 여파로 EKS, ECS, Fargate 의 컨테이너 시작과 클러스터 스케일링이 14시간 넘게 막혔다Amazon Web Services · 2025같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0527OpenStreetMap.org 의 복제 diff 생성이 invalid memory alloc request size 오류로 16시간 멈춤OpenStreetMap Foundation · 2025같은 원인 · 공통 데이터베이스
IL-0329Postgres 17 업그레이드 뒤 다시 켠 PGAudit 가 마이그레이션 중 락을 쥔 채 멈춰, 서비스 전반이 느려지고 데이터베이스가 2분 동안 내려갔다incident.io · 2025같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0024무거운 API 요청이 MongoDB 에 과부하를 걸고 취소되지 않은 요청이 쌓여 Hugging Face Hub 가 사흘 동안 세 번 멈췄다Hugging Face · 2024같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스 장애 조치 관리자
IL-0385큰 MySQL 테이블의 스키마 마이그레이션 마지막 단계에서 읽기 복제본 다수가 semaphore deadlock 에 걸려 GitHub 핵심 서비스가 2시간 50분 저하됐다GitHub · 2021같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0196Redis Operator 로 레플리카를 늘리면서 메모리 한도를 낮추자 데이터를 가진 유일한 Redis 파드가 재시작됐고, Sentinel 이 빈 레플리카를 마스터로 올려 데이터가 모두 지워졌다.Palark · 2020같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0388Redis 고가용 클러스터의 primary 노드가 내려간 뒤 Discord API 가 느려지고 길드 일부가 오프라인으로 보이며 접속이 실패했다Discord · 2017같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0310
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0310/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.