그래프
사례4건
4건 중 1~4번째
- 증상
인스턴스 크기를 키우려고 Aurora 클러스터에서 장애 조치를 실행했다. 새 writer 로 올라가던 instance #2 는 잠깐 승격됐다가 곧 되돌아갔고, 원래 writer 인 instance #1 이 primary 로 남았다. AWS 콘솔에서는 클러스터가 모두 정상으로 보였지만 백엔드 서비스는 쓰기 쿼리를 실행하지 못했다.
- 촉발
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 가 잠깐 바뀐 일은 인스턴스별 쿼리 모니터링과 데이터베이스 로그가 있어서 찾을 수 있었다. 큰 분산 시스템에서는 구성 요소 하나가 시스템에 미치는 영향을 격리해 두면 가동 시간과 유지 보수 모두에 도움이 된다. 스테이징의 부하 시험은 운영 환경을 그대로 재현하지 못했고, 이번 레이스 컨디션을 일으킨 조건도 재현하지 못했다.
- 증상
2022-04-11 10:42 UTC 부터 mt1 클러스터에서 Channels 메시지 발행 API 를 11분 동안 거의 쓸 수 없었다. 상태 페이지는 10:44 무렵부터 10:53 무렵까지 MT1 API 요청의 오류율이 올랐다고 알렸다.
- 촉발
엔지니어는 Redis 설정의 복제 버퍼를 키운 것을 반영하려고 mt1 클러스터의 노드를 하나씩 교체하다가, 10:42 UTC 에 마스터 노드를 재시작했다. 장애 조치는 시작됐지만 끝나기 전에 Redis 프로세스가 종료됐다.
- 원인
- 구성 요소
- 기여 요인
- 감지
Pusher 는 10:44 UTC 무렵부터 MT1 API 요청의 오류율이 오른 것을 확인하고 상태 페이지에 알렸다.
- 후속 조치
- Redis 종료 스크립트가 노드를 끄기 전에 장애 조치가 끝났고 그 노드가 더는 마스터가 아닌지 확인하도록 고친다.
- 증상
2019년 7월 10일 16:35 UTC 에 데이터베이스 클러스터의 primary 노드가 고장 났고, 1분 뒤 자동 모니터링이 선출 실패를 잡아 알림을 보냈다. Stripe API 요청 대부분이 실패하기 시작했다.
- 촉발
16:35 UTC 에 데이터베이스 클러스터의 primary 노드가 고장 났다. 그 shard 에는 멈춘 노드가 여럿 있어 석 달 전 마이너 버전 업그레이드로 들어온 장애 조치 결함이 드러났다. 두 번째 장애는 선출 프로토콜을 이전 마이너 버전으로 되돌린 변경 때문에 일어났다.
- 원인
- 구성 요소
- 기여 요인
- 감지
첫 장애는 자동 모니터링이 1분 안에 선출 실패를 잡았고, 16:36 UTC 에 팀이 알림을 받아 대응을 시작했다. 두 번째 장애는 21:14 UTC 에 클러스터의 shard 몇 개를 사용할 수 없다는 자동 알림으로 알았다.
- 조치
- 17:00 UTC 에 데이터베이스 클러스터의 모든 노드를 재시작해 새 primary 선출을 성공시켰다. 17:02 에 Stripe API 가 완전히 복구됐다.
- 22:34 UTC 에 운영 설정을 고쳐 새로 배포하고 데이터베이스 클러스터의 노드를 재시작해 영향받은 shard 를 되살렸다.
- 클러스터가 정상인지 확인한 뒤 사용자가 직접 보낸 API 요청에 필요한 서비스부터 트래픽을 다시 올렸다. 22:47 UTC 에 완전히 복구됐다.
- 후속 조치
- 노드가 복제 지연 지표를 보내지 않으면 알리는 모니터링을 더했다.
- shard 가 데이터베이스 장애 조치 시스템의 이 선출 결함을 일으킬 수 있는 상태에 들어가면 알리는 모니터링을 더했다.
- 이 결함을 고치는 수정을 데이터베이스 메인테이너와 함께 만든다.
- 특정 클러스터로 가는 작업이 실패하면 끊어 내는 서킷 브레이커를 더 넣는다. 이번 사고의 클러스터도 대상이다.
- shard 하나가 고장 나도 그 영향을 가두는 장애 격리 기법을 더 도입한다.
- 실패한 요청을 거듭 재시도하는 클라이언트가 쓰는 자원을 제한한다.
- 장애 대응 중 운영자가 설정을 빠르게 바꿀 때 더 안전하게 할 수 있도록 절차와 도구를 더 만든다.
- 증상
2012년 9월 10일 월요일, 스키마 마이그레이션이 데이터베이스에 높은 부하를 걸자 Percona Replication Manager 의 헬스 체크가 마스터에서 실패했다. Percona Replication Manager 는 'active' 역할을 다른 노드로 옮겼고, 새 노드가 느려지면서 GitHub.com 이 멈췄다.
- 촉발
무중단 MySQL 스키마 마이그레이션이 이전의 같은 종류 마이그레이션보다 높은 부하를 데이터베이스에 걸었고, 그 부하로 Percona Replication Manager 의 헬스 체크가 마스터에서 실패했다.
- 원인
- 구성 요소
- 기여 요인
- 감지
9월 11일 아침 한 개발자가 'standby' 역할을 맡은 노드에서 잘못된 쿼리 결과가 나온다고 운영팀에 알렸다. 그 뒤 운영팀은 혼자 마스터로 뽑힌 'c' 노드가 앞서 데이터가 뒤처졌다고 판단한 노드라는 것을 알아챘다.
- 조치
- 9월 10일 Pacemaker 의 maintenance-mode 를 켜서 모든 헬스 체크와 자동 페일오버 동작을 멈췄다.
- 9월 11일 8:26 AM 에 데이터가 뒤처진 'c' 노드의 전원을 꺼서 갈라진 클러스터 상태를 끝내고 데이터가 더 어긋나지 않게 했다.
- 클러스터 상태를 깨끗하게 되살리려고 'a' 와 'b' 두 노드에서 Pacemaker 와 Heartbeat 프로세스를 모두 멈춘 뒤 'a' 노드에서 다시 띄웠다.
- 'a' 노드에서 MySQL 을 띄워 'active' 역할을 맡게 했다.
- 다른 사용자의 대시보드에 새어 나간 이벤트를 모두 지우고, 그 시간에 경로가 잘못 잡힌 저장소를 모두 점검했다.
- 협업자가 아닌 사람에게 열려 있던 비공개 저장소 16개의 소유자에게 모두 직접 연락했다.
- 후속 조치
- Pacemaker 설정을 바꿔 'active' 데이터베이스 역할의 페일오버는 운영팀 사람이 시작할 때만 일어나게 한다.
- 비상시나 정기 유지보수 때 페일오버를 해도 성능이 떨어지지 않도록, 복제본 데이터베이스의 InnoDB 버퍼 풀을 미리 데우는 여러 방법을 조사하고 시험한다.
- 화요일에 segfault 를 일으킨 코드 경로를 중심으로 Pacemaker 와 Heartbeat 스택 전체를 점검한다.
- 만일에 대비해 segfault 가 난 서버에서 강도 높은 하드웨어 시험을 한다.
- 교훈
GitHub 은 이번 장애에 세 가지가 겹쳤다고 밝혔다. 일어나지 말았어야 할 'active' 역할 페일오버가 여러 번 일어났고, 클러스터 상태가 갈라져 클러스터 관리 소프트웨어가 잘못된 동작을 했으며, 그 페일오버들이 필요 이상으로 성능과 가용성을 해쳤다. 두 장애는 모두 자동 페일오버에서 시작했는데, 그 페일오버를 해야 하느냐고 운영팀 누구에게 물었어도 하지 말아야 한다고 답했을 것이다. GitHub 은 자동 페일오버가 서비스 가용성을 지키는 좋은 방법인 경우가 많지만, 주 운영 데이터베이스는 그런 경우가 아니라고 결론 내렸다.
이 4건에서 가장 많이 나오는 구성 요소: 데이터베이스 장애 조치 관리자, 데이터베이스. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.
원인별1
소프트웨어 결함4건
IL-0310Aurora PostgreSQL 의 수동 장애 조치가 스스로 되돌아가 원래 writer 가 남고 백엔드의 쓰기 쿼리가 실패했다Hightouch2025IL-0295Pusher Channels mt1 클러스터의 메시지 발행 API 가 Redis 장애 조치 도중 11분 동안 거의 멈췄다Pusher2022IL-0241데이터베이스 shard 하나가 primary 를 뽑지 못해 Stripe API 요청 대부분이 두 차례 실패했다Stripe2019IL-0303GitHub 의 새 3노드 MySQL 클러스터에서 자동 페일오버가 잘못 일어나고 클러스터 상태가 갈라져 GitHub.com 이 두 번 멈췄다GitHub2012