Incident Library

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 알림이 잡았다. 온콜 호출을 받은 사람은 없었다.

조치

후속 조치

교훈

원형 복제는 평소 운영 방식이 아니어서 heartbeat 테이블을 지우는 첫 조치가 문제를 eqiad 에서 codfw 로 옮기기만 했다. TRUNCATE 는 DDL 이라 늘 STATEMENT 모드로 전달되므로 이번에는 DELETE 보다 나았겠지만, 더 위험해서 고려하지 않았다. ROW 기반 복제, pt-heartbeat, 서버마다 다른 heartbeat 테이블 행이 겹친 문제는 이전 유지 보수 기록에 없었다. 자동화의 점검은 설정 직후 한 번이 아니라 모든 작업이 끝난 뒤에도 복제 채널을 확인했어야 했다. Wikimedia 는 어느 호스트에서도 sql_skip_slave_counter 를 쓰지 않아 더 큰 문제나 데이터 손실을 피한 것을 잘된 점으로 꼽았다.

출처

참고 문서

관련 사례

내 클러스터에도 있는지 확인하기

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 데이터베이스, 데이터베이스 복제. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.