사례2건
2건 중 1~2번째
- 증상
matrix.org 홈서버 사용자들이 방이 그냥 멈춘다고 보고했다. 새 메시지를 보내거나 새 멤버가 방에 들어가는 일이 이유 없이 실패했고, 오류 문구가 보일 때는 대개 "No create event in auth events" 였다.
- 촉발
matrix.org 의 PostgreSQL 테이블 state_groups_state 에서 오래전에 손상된 인덱스 영역에 Postgres 가 새 행을 채우기 시작했고, 쓰이지 않는 오래된 데이터를 지우는 백그라운드 정리 작업이 최근 그 영역을 다루기 시작했다.
- 원인
- 구성 요소
- 기여 요인
- –
- 감지
사용자의 버그 보고와 공개 Matrix 방, 다른 소셜 미디어의 비슷한 보고로 문제를 알았다. 보고가 더 쌓이자 팀이 조사를 시작했다.
- 조치
- 예방 조치로 쓰이지 않는 state group 을 지우는 정리 작업을 잠시 껐다.
- 데이터를 백업에서 되살려야 할 것으로 보고 6월 26일 데이터베이스 백업을 Amazon EC2 의 새 Postgres 인스턴스에 복원하기 시작했다.
- 아직 쓰이는 state group 의 상태를 지우려는 SQL 쿼리를 거부하는 Postgres 제약을 걸어 손상이 더 번지지 않게 했다.
- 4 TB 가 넘는 손상된 인덱스를 밤새 다시 만들었다.
- 정리 작업이 다룬 범위의 state group 을 복원한 백업에서 조회해 피해 후보를 뽑고, 운영 데이터베이스와 대조해 지워졌지만 아직 쓰이는 state group 을 찾아 운영 데이터베이스에 하나씩 다시 넣었다.
- 교훈
이 손상은 몇 달이나 몇 년 동안 아무도 모르게 있을 수 있었다. 인덱스가 힙의 빈 자리를 가리키는 동안에는 드러나지 않았고, Postgres 가 그 자리에 새 행을 채우기 시작한 뒤에야 문제가 보였다. pg_amcheck 는 이런 손상을 찾지 못했지만, 테이블의 모든 행이 인덱스에 있다는 것은 확인해 줘서 인덱스 행이 빠진 것이 아니라 남는 행이 있다는 것을 알 수 있었다. 팀은 이런 장애가 큰 규모의 서비스를 운영하면 가끔 일어나고, 미리 계획할 수 없으며, 기능 개발이나 버그 수정에 쓸 사람의 시간과 노력을 크게 잡아먹는다고 정리했다.
- 증상
2022-03-27 3:23 UTC 에 계정, 서버, 플레이어 정보를 담는 주 PostgreSQL 데이터베이스가 쓰기를 받지 않았다. 처음 보인 증상은 사용자가 웹사이트를 불러오지 못하는 것이었다.
- 촉발
플레이어 식별자 테이블의 인덱스가 알 수 없는 이유로 손상돼 vacuum 작업이 모두 오류로 끝났다. 로그로 보아 손상은 약 한 달 전인 2022-02-26 에 생긴 것으로 추정했고, 그동안 트랜잭션 ID 가 계속 쌓여 2022-03-27 에 wraparound 보호가 작동했다.
- 원인
- 구성 요소
- 기여 요인
- 감지
처음 들어온 것은 웹사이트를 불러오지 못한다는 사용자 신고였다. 팀은 30분쯤 전에 작동한 DDoS 방어 탓으로 보았다가, RCON 업데이트와 쿼리가 실패하는 것을 보고 더 살펴본 끝에 주 데이터베이스가 쓰기를 받지 않는 것을 찾았다.
- 조치
- 데이터베이스를 내리고 single-user mode 로 들어가 손상된 인덱스를 지운 뒤 데이터베이스를 다시 올렸다.
- vacuum 을 다시 돌렸고, 이번에는 성공해 데이터베이스가 다시 쓰기를 받았다.
- 지운 플레이어 식별자 인덱스를 약 두 시간에 걸쳐 다시 만들었다.
- 데이터베이스가 돌아온 뒤 쿼리 워커를 모두 멈추고 RCON 업데이트를 우선했다.
- 인덱스가 돌아오자 서비스가 새 Postgres primary 를 가리키게 했다.
- replica 를 더 부트스트랩해 하나 올라올 때마다 primary 부하를 덜었고, 16:30 UTC 에 RCON 업데이트를 따라잡았다.
- RCON 업데이트가 늦어지지 않게 쿼리를 제한해서 다시 돌렸고, 쿼리의 우선순위는 서버의 현재 접속 인원과 순위로 매겼다.
- 후속 조치
- Postgres 로그의 오류를 모니터링한다.
- 트랜잭션 ID 를 모니터링하고 알림을 건다.
- 물리 복제에 더해 논리 replica 를 둔다.
- 장애에서 더 빨리 복구하도록 더 빠른 네트워크를 갖춘다.
- 교훈
BattleMetrics 는 Postgres 의 트랜잭션 ID 크기를 확인하는 헬스 체크를 두지 않은 것을 결정적인 실수로 보았다. 인덱스 손상은 사이트 성능에 영향이 없어 한 달 동안 드러나지 않았고, 그동안 vacuum 이 계속 실패하며 데이터베이스가 wraparound 에 다가갔다. 손상은 replica 에도 복제돼 있어 장애 조치가 소용없었고, 백업 서버와 내려받기용 백업도 같은 손상을 안고 있었다. 오류 문구와 달리 wraparound 보호에 들어간 서버에서도 single-user mode 없이 전체 vacuum 을 돌릴 수 있었다.
이 2건에서 가장 많이 나오는 구성 요소: 데이터베이스, PostgreSQL vacuum. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.