IL-0392 Wikimedia Foundation · 2024-09-18database
데이터센터 전환을 앞두고 원형 복제를 설정하던 중 Wikimedia x1 섹션의 eqiad·codfw 사이 MariaDB 복제가 6분 멈췄다
Wikimedia Foundation 은 다음 주 데이터센터 전환을 앞두고 2024년 9월 18일 핵심 데이터베이스를 eqiad 에서 codfw 로 가는 한 방향 복제에서 원형 복제로 바꾸는 cookbook 을 돌렸다. 시험을 위해 codfw 를 유일한 활성 primary 데이터센터로 두는 동안에도 데이터가 eqiad 로 자동으로 흘러가게 하려는 것이었다. cookbook 은 STATEMENT 기반 복제 섹션인 s1 부터 s8 까지는 문제없이 끝냈다. ROW 기반 복제를 쓰는 x1 섹션에 codfw 에서 eqiad 로 가는 복제를 설정하고 pt-heartbeat 를 시작하자 문제가 생겼다. 앞선 정리 작업으로 heartbeat 행이 지워져 있어서, pt-heartbeat 의 쓰기가 codfw 서버에서는 기존 행을 갱신했지만 eqiad 서버에는 그 행이 없었다. pt-heartbeat 는 REPLACE 로 upsert 를 하므로 STATEMENT 기반 복제에서는 문제가 없다. 그러나 ROW 형식은 행 쓰기, 또는 행 삭제 뒤 새 행 쓰기만 표현할 수 있다. 그 결과 eqiad 의 x1 서버에서 복제가 "missing row" 오류로 멈췄고, es6 섹션도 같이 깨졌다.
원형 복제 모니터링이 아직 켜지지 않아 처음에는 알림이 없었고, 21:28 UTC 쯤 엔지니어가 orchestrator 에서 x1 primary master 가 복제하지 않는 것을 직접 봤다. heartbeat 테이블 행을 모두 지우자 eqiad 쪽 문제는 풀렸지만 문제가 codfw 로 옮겨 가, 21:42:19 UTC 부터 eqiad 에서 codfw 로 가는 x1 복제가 멈췄다. 이것이 사용자 영향의 시작이었다. 21:48:19 UTC 에 heartbeat 복제를 건너뛰는 임시 조치를 넣어 복제가 다시 흘렀다. 이어 binlog 기록을 끈 채 빠진 heartbeat 행을 호스트마다 직접 넣는 제대로 된 조치를 es6 에서 시험하고 es7 에 미리 적용했다. cookbook 은 22:11:55 UTC 에 마지막 ROW 섹션까지 끝냈고, x1 codfw 호스트에도 같은 방식의 조치를 넣어 임시 조치를 대신했다.
나중에 조사해 보니 처음 시험한 고침은 문제를 다른 primary 서버로 옮길 뿐이었다. 원인은 한 변경과 Orchestrator 도입 뒤 생긴 pt-heartbeat 여분 행을 지우는 정리 절차가 겹친 것으로 좁혀졌다. 그 결과 ROW 를 쓰는 x1 과 읽기·쓰기 es 호스트에서 pt-heartbeat-wikimedia 가 자기 세션을 STATEMENT 로 덮어쓰지 않았다. 이 문제는 이후 배포로 고쳤다.
- 심각도
- –
- 영향 범위
- For 6 minutes replication of the x1 section between eqiad and codfw stopped; x1-based services such as reading lists and echo could have served stale data, with no visible errors
- 영향 사용자
- Clients in the Americas
- 지역
- codfw
- 감지까지
- –
- 복구까지
- 6m
증상
2024년 9월 18일 데이터센터 전환을 앞두고 cookbook 으로 원형 복제를 설정하던 중, 21:28 UTC 쯤 엔지니어가 x1 섹션의 primary master 가 복제를 하지 않는 것을 orchestrator 에서 먼저 알아챘다. es6 섹션도 같은 상태였다.
eqiad 의 x1 서버에서 복제가 "missing row" 오류로 멈췄다. 복제 오류는 Could not execute Update_rows_v1 event on table heartbeat.heartbeat; Can't find record in 'heartbeat' 였다.
첫 조치로 heartbeat 행을 지우자 eqiad 쪽은 풀렸지만 문제가 codfw 로 옮겨 갔다. 21:42:19 UTC 에 Icinga 가 PROBLEM - MariaDB Replica SQL: x1 on db2196 is CRITICAL: CRITICAL slave_sql_state Slave_SQL_Running: No, Errno: 1062, Errmsg: Could not execute Write_rows_v1 event on table heartbeat.heartbeat: Duplicate entry 180360966 for key PRIMARY 알림을 냈다. 이때부터 eqiad 에서 codfw 로 가는 x1 복제가 6분 멈췄다.
눈에 보일 만한 오류는 나지 않았다. reading lists 와 echo 를 비롯해 x1 을 쓰는 서비스가 아메리카 지역 클라이언트에게 한동안 오래된 데이터를 보여 줬을 수 있었다.
cookbook 의 설정 후 점검은 통과했다. 복제가 바로 깨지지 않고 codfw 에서 pt-heartbeat 가 다시 시작된 뒤에야 깨졌기 때문이다. 원형 복제의 일반 모니터링은 아직 켜기 전이어서 codfw 에서 eqiad 로 가는 방향의 고장은 모니터링이 잡지 못했다.
증상 복제 지연
원인
- 촉발
- 다음 주 데이터센터 전환을 앞두고 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 를 쓰지 않아 더 큰 문제나 데이터 손실을 피한 것을 잘된 점으로 꼽았다.
출처
참고 문서
- https://wikitech.wikimedia.org/wiki/MariaDB/troubleshooting#Data_inconsistency_between_nodes_%22drift%22_/_replication_broken
- https://gerrit.wikimedia.org/r/c/operations/cookbooks/+/1074127
- https://gerrit.wikimedia.org/r/c/operations/software/spicerack/+/1074111
- https://gerrit.wikimedia.org/r/c/operations/cookbooks/+/1074128/1
관련 사례
같은 원인 · 공통 데이터베이스, 데이터베이스 복제
같은 원인 · 공통 데이터베이스, 데이터베이스 복제
IL-0574운영 환경의 DB 접속 경로를 Amazon RDS Proxy로 바꾼 지 몇 분 만에 Aurora MySQL writer CPU가 100%에 이르고 에러가 났다Safie · 2026같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0179DEBUG 로그가 쏟아지자 동기 로깅을 하던 요청 스레드들이 가득 찬 stdout 파이프에서 멈춘 채 DB 커넥션을 쥐고 있어, HikariCP 커넥션 풀이 고갈되고 요청이 30초 주기로 한꺼번에 실패했다.MUSINSA · 2026같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0283Cloudflare 네트워크 전체에서 코어 프록시가 Bot Management 피처 파일을 읽다 실패해 사이트 방문자들이 HTTP 5xx 오류 페이지를 받았다Cloudflare · 2025같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스 복제
IL-0367Central US 의 Azure Storage 가 VM 디스크 요청을 거부해 VM 과 그 위의 SQL Database, Cosmos DB 가 멈췄다Microsoft Azure · 2024같은 원인 · 공통 데이터베이스
IL-0511Vault 가 새로 발급한 데이터베이스 자격 증명이 SCRAM 으로 만들어져 pgbouncer 가 RDS 에 로그인하지 못하고 xPro 운영 사이트가 멈췄다MIT Open Learning · 2023같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스 복제
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스 복제
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0392
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0392/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.