그래프
사례2건
2건 중 1~2번째
- 증상
2026년 8월 24일 16:56 UTC 부터 DigitalOcean 의 Cloud Control Panel, 공개 API, 그리고 이 둘에 기대는 제품 관리 시스템에서 요청 오류율이 올라갔다. 여러 제품의 생성 요청을 포함한 모든 API 요청에서 5xx 오류가 늘었고, 사용자가 cloud.digitalocean.com 에 들어가지 못하기도 했다.
- 촉발
아이덴티티, 인증, 인가 서비스를 받치는 데이터베이스 계층을 계획에 따라 이전하는 인프라 작업을 하던 중이었다. 이 이전 작업 때문에 핵심 인가 쿼리 하나의 실행 지연이 늘었다.
- 원인
- 구성 요소
- 기여 요인
- 감지
16:58 UTC 에 자동 모니터링이 비정상적인 오류율과 지연을 잡아냈다. 보고서는 영향이 시작되고 5분 안에 감지했다고 적었다.
- 조치
- 인가 트래픽을 정상으로 동작하는 처리 경로 하나로 몰아 보냈다.
- 주요 호출자의 hedging 을 잠시 껐다.
- 두 번째 구간에서 나머지 영향받은 서비스 전체의 재시도와 요청 증폭 동작을 껐다.
- 느린 인가 쿼리를 받을 읽기 용량을 더했다.
- 후속 조치
- 상위 서비스 전반에 자동 서킷 브레이커를 배포했다. 서킷 브레이커는 하위 의존 서비스가 나빠진 것을 감지하면 hedged retry 와 재시도 증폭을 자동으로 막는다.
- 모든 컨트롤 플레인 서비스에 재시도 억제와 서킷 브레이커가 똑같이 적용되는지 아키텍처 전반을 점검하는 작업을 마쳤다.
- 의존 서비스가 느려질 때 요청 큐가 포화되지 않도록 요청을 빠르게 실패시키는 로드 셰딩을 넣었다.
- 고객이 영향을 받기 전에 큐가 쌓이기 시작한 것을 알아채는 텔레메트리 알림을 더했다.
- 주 데이터베이스가 느려지면 핵심 인가 구성 요소가 기능을 줄인 모드로 동작하도록 설정했다. 이 모드에서는 비동기로 갱신되는 최종 일관성 복제본을 읽는다.
- 증상
2024년 9월 18일 데이터센터 전환을 앞두고 cookbook 으로 원형 복제를 설정하던 중, 21:28 UTC 쯤 엔지니어가 x1 섹션의 primary master 가 복제를 하지 않는 것을 orchestrator 에서 먼저 알아챘다. es6 섹션도 같은 상태였다.
- 촉발
다음 주 데이터센터 전환을 앞두고 cookbook 이 핵심 데이터베이스를 eqiad 에서 codfw 로 가는 한 방향 복제에서 원형 복제로 바꿨다. ROW 기반 복제를 쓰는 x1 섹션에 codfw 에서 eqiad 로 가는 복제를 설정하고 pt-heartbeat 를 시작하자, eqiad 서버에 없는 heartbeat 행을 갱신하려다 복제가 멈췄다.
- 원인
- 구성 요소
- 기여 요인
- 감지
원형 복제의 일반 모니터링이 아직 켜지지 않아, 엔지니어가 orchestrator 에서 먼저 알아챘다. 복제 자동화가 처음 도는 날이라 평소보다 많은 사람이 데이터베이스 상태를 지켜보고 있었다. 사용자에게 영향을 준 eqiad 에서 codfw 로 가는 방향의 고장은 Icinga 알림이 잡았다. 온콜 호출을 받은 사람은 없었다.
- 조치
- SET GLOBAL Replication_wild_ignore_table='heartbeat.%'; 로 heartbeat 테이블 복제를 건너뛰게 해 복제가 다시 흐르게 했다.
- es 호스트에는 원래 고장이 난 방향에 맞춰, binlog 기록을 끈 채 eqiad 서버마다 빠진 codfw heartbeat 행을 직접 넣었다. 명령은 set sql_log_bin=0; INSERT INTO heartbeat.heartbeat (server_id, shard, datacenter) VALUES (<codfw-server-id>, 'es6' [or 'es7'], 'codfw'); 였다. es6 에서 먼저 시험했고, es7 에는 원형 복제를 설정하기 전에 미리 넣었다.
- x1 codfw 호스트마다 binlog 기록을 끈 채 빠진 heartbeat 행을 넣어, 임시로 걸어 둔 heartbeat 무시 설정을 대신했다. 명령은 set sql_log_bin=0; INSERT INTO heartbeat.heartbeat (server_id, shard, datacenter) VALUES (<eqiad-server-id>, 'x1', 'eqiad'); 였다.
- 후속 조치
- 같은 문제를 다시 겪지 않게 한다. 빠진 행을 찾으면 직접 넣는 방식을 유력하게 본다.
- 유지 보수 뒤 복제가 의도대로 양방향으로 동작하는지 확인하는 상태 점검을 cookbook 에 넣는다.
- 유지 보수를 다른 순서로, 또는 섹션마다 따로 돌릴 수 있는 옵션을 더한다.
- Phabricator 를 마지막에 한 번만 갱신하지 않고 섹션마다 갱신한다.
- 모니터링의 빈틈을 메운다.
- x1 과 ROW 를 쓰는 읽기·쓰기 es 호스트에서 pt-heartbeat-wikimedia 가 자기 세션을 STATEMENT 로 쓰도록 고쳐 배포했다.
- 교훈
원형 복제는 평소 운영 방식이 아니어서 heartbeat 테이블을 지우는 첫 조치가 문제를 eqiad 에서 codfw 로 옮기기만 했다. TRUNCATE 는 DDL 이라 늘 STATEMENT 모드로 전달되므로 이번에는 DELETE 보다 나았겠지만, 더 위험해서 고려하지 않았다. ROW 기반 복제, pt-heartbeat, 서버마다 다른 heartbeat 테이블 행이 겹친 문제는 이전 유지 보수 기록에 없었다. 자동화의 점검은 설정 직후 한 번이 아니라 모든 작업이 끝난 뒤에도 복제 채널을 확인했어야 했다. Wikimedia 는 어느 호스트에서도 sql_skip_slave_counter 를 쓰지 않아 더 큰 문제나 데이터 손실을 피한 것을 잘된 점으로 꼽았다.
이 2건에서 가장 많이 나오는 구성 요소: 데이터베이스, 데이터베이스 복제. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.