Incident Library
적용된 필터 원인용량 한계증상처리량 저하기여 요인초기 신호 무시모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례4건

4건 중 1~4번째

  1. 증상

    2026년 10월 6일 13시 30분 UTC부터 CircleCI 의 워크플로 조율 서비스가 느려져 일부 파이프라인과 잡이 이따금 조금씩 늦게 시작했다. 15시 30분부터는 지연이 계속 이어졌고 일부 잡이 실패하기 시작했다.

    촉발

    10월 6일 12시 40분쯤 데이터베이스의 가장 큰 테이블 몇 개에서 돌던 정기 유지 보수 작업인 anti-wraparound autovacuum 이 평소 작업량과 겹치면서, 데이터베이스가 트랜잭션 로그를 보관 처리하는 속도보다 빠르게 로그를 썼다.

    원인
    구성 요소
    기여 요인
    감지

    10시 2분부터 모니터링이 조율 서비스의 오류 알림을 짧게 여러 번 냈지만 매번 저절로 풀렸다. 13시 35분에 여러 다른 서비스의 관련 알림과 함께 다시 울렸고, 14시 30분쯤 알림이 다시 울리자 더 조사한 뒤 14시 54분에 장애를 선언했다. 트랜잭션 로그 볼륨이 얼마나 찼는지와 보관 처리가 얼마나 밀렸는지를 보는 알림은 없었다. 상태 페이지에는 15시 58분에 공지를 올렸고 16시 20분에 주요 장애로 올렸다.

    조치
    • anti-wraparound autovacuum 이 빨리 끝나도록 설정을 바꿨다. 이 작업은 취소하면 데이터베이스가 자동으로 다시 시작하기 때문이었다.
    • 트랜잭션 로그 볼륨이 거의 차자 데이터베이스가 읽기 전용이 되지 않도록 로그를 여유 공간이 많은 데이터베이스의 주 저장 볼륨으로 옮겼다. 옮기는 동안 데이터베이스가 50분 동안 내려갔다.
    • 유지 보수 작업이 더 시작되지 않도록 데이터베이스 파라미터 몇 가지를 조사해 바꿨다.
    • 18시 19분에 쓰기마다 저장소를 기다리는 시간을 줄이는 데이터베이스 설정을 바꿔 처리 속도를 되살렸다.
    • 밀린 작업을 빨리 처리하려고 잡을 실행 플릿에 넘기는 시스템에 데이터베이스와 서버 용량을 더했다.
    후속 조치
    • 트랜잭션 로그 볼륨이 얼마나 찼는지와 보관 처리가 얼마나 밀렸는지에 알림을 건다.
    • 이 두 상태를 일으키는 데이터베이스 유지 보수 작업에도 알림을 걸어 더 일찍 대응한다.
    • 시끄럽거나 지나치게 민감한 알림이 실제 문제를 가리지 않도록 모든 알림을 다시 살핀다.
    • 데이터베이스의 autovacuum 이 얼마나 자주, 얼마나 공격적으로 도는지를 조정한다.
    • 큰 테이블들의 크기를 시간에 따라 추적해 안전한 한계 안에 두게 한다.
    • 트랜잭션 로그 하나에 모든 쓰기가 몰리는 병목을 없앤다. 서비스를 각자 트랜잭션 로그를 가진 여러 데이터베이스 인스턴스로 나누는 방법과, 쓰기를 여러 노드에 나누는 분산 데이터베이스로 옮기는 방법을 검토한다.
    • 다른 시스템들이 재시도 끝에 포기하지 않고 조율 서비스가 회복할 때까지 기다리도록 동작을 바꾼다.
    • 긴 장애 동안 상태 페이지 공지가 구체적인 영향과 시각을 더 일찍 담도록 지침을 고친다.
    교훈

    CircleCI 는 여러 알림이 함께 울린 것을 더 일찍 알아챘어야 했다고 밝혔다. 모니터링은 느려진 것을 잡았지만 트랜잭션 로그 볼륨이 찬 정도와 보관 처리가 밀린 정도에는 알림이 없었다. 조율 서비스의 모든 쓰기가 데이터베이스 하나와 트랜잭션 로그 하나를 거치기 때문에, 그 로그가 밀리자 모든 파이프라인, 워크플로, 잡이 함께 느려졌다. 일부 잡은 다른 시스템들이 재시도 끝에 포기해서 실패했다. 고객들은 초기 상태 페이지 공지에 세부 내용이 부족했다고 알려 왔다.

  2. 증상

    13:30 UTC 에 ZooKeeperWait 지표가 갑자기 오른다는 알림이 왔다. 이 클러스터의 알림 기준은 낮은 쪽 10초, 높은 쪽 20초인데 값은 수천 초였다. 값은 대칭으로 이중화된 인스턴스 세 곳에서 똑같이 올랐다.

    촉발

    몇 달 동안 네트워크에서 떨어져 있던 클라이언트 머신 두 대가 다시 연결되면서, 그동안 쌓인 몇 달 치 헬스 체크 데이터를 아주 작은 배치로 빠르게 보냈다.

    원인
    구성 요소
    기여 요인
    감지

    13:30 UTC 에 팀은 ZooKeeperWait 지표가 갑자기 오른다는 알림을 받았다. 이 클러스터 크기에 맞춘 알림 기준은 낮은 쪽 10초, 높은 쪽 20초였다.

    조치
    • 쌓인 파트를 끝내 정리하지 못한 5분 단위 파티션 테이블을 장애 뒤 DROP-CREATE 로 다시 만들어 정상으로 되돌렸다.
    • 그 테이블의 파티션 단위를 분에서 시간으로 넓혔다.
    후속 조치
    • 루트 MaterializedView 테이블에서 범위를 벗어난 타임스탬프를 거부하도록 구현했다.
    • 두 번째 MaterializedView 가 거부된 데이터의 통계를 기록한다.
    • 거부 범위는 과거 데이터 백필을 위해 일부러 넓게 잡았고, 거부되는 데이터를 모아 가며 범위를 다듬는다.
    • 타임스탬프가 며칠이나 몇 달에 걸친 insert 쿼리 하나로 이번 상황을 재현하는 최소 시험 시나리오를 만들었다.
    • 관측 기능을 여러 가지 개선한다.
    교훈

    이 파이프라인은 주로 데이터 양을 다루지만, 어긋난 타임스탬프도 카디널리티 변화만큼 파이프라인을 흔들 수 있었다. 이상한 지표를 바로 설명하지 못했다고 치워 두면 안 된다. 이번에도 원인으로 이끈 것은 처음에 무시한 insert 크기 감소였다. 중앙값과 평균은 각자 쓸모가 있고, 이번에는 평균이 실마리였다. 파티션이 너무 적으면 파트가 커지고 mutation 이 느려지며 TTL 이 너무 비싸지거나 아예 동작하지 않는다. 반대로 너무 많으면 열 스캔과 집계 쿼리가 느려지고 Keeper 가 과부하된다. Keeper 작업은 파트 수에 따라 선형보다 훨씬 빠르게 늘었다.

  3. 증상

    2019년 5월 30일 13:26 PDT 에 Slack 으로 Prow 가 이상하다는 신고가 들어왔다. GitHub 에는 잡이 실패했다고 올라왔는데 Deck 에서는 같은 잡이 아직 실행 중으로 보였다. 많은 테스트가 뜻밖의 방식으로 실패하거나 실행 도중 뚜렷한 이유 없이 중단됐다.

    촉발

    Kubernetes 1.15 code freeze 를 앞두고 테스트 사용량이 치솟아, k8s-prow-build 클러스터 노드의 디스크 I/O 가 GCP 의 스로틀링 한도에 걸렸다.

    원인
    구성 요소
    기여 요인
    감지

    여러 사용자가 GitHub 에는 실패로 올라왔지만 잡 상태로는 아직 실행 중인 잡이 있다고 신고했다. 첫 신고는 13:26 에 Slack 으로 들어왔다. 이런 장애를 잡는 알림은 없거나 동작하지 않았다.

    조치
    • 디스크 quota 를 더 요청해 15:14 에 받았다.
    • 17:10 에 500 GB 디스크 노드 55개를 띄웠다.
    • 23:55 에 새 노드 풀로 옮기는 일을 마쳐 모든 노드가 500 GB 디스크를 쓰게 됐다.
    후속 조치
    • tide 가 일을 멈추면 온콜 담당자가 호출을 받도록 모니터링을 만들거나 고친다. 이 일은 이슈 #12829 에서 다룬다.
    • 온콜 순번에 새 사람을 넣는 절차와 지침을 만들어, 새 사람이 준비나 추가 지원 없이 혼자 맡겨지지 않게 한다.
    교훈

    사고 전에 Prow 지표가 기록되지 않아 무슨 일인지 파악하기 어려웠다. 이런 장애를 잡는 알림은 없거나 동작하지 않았다. 원인을 찾고 해결책을 정한 뒤에도 두 시간 동안 아무것도 하지 않았다. 사고로 1.15 code freeze 가 밀렸다. IOPS 가 문제라는 것을 알아본 사람이 마침 자리에 있었던 것은 운이었다.

  4. 증상

    2019년 2월 4일 05:35 UTC 부터 Mandrill 이 대기열에 쌓인 메일의 80% 만 보냈다. 첫 예외는 일요일 밤에 로그에 남았지만 다른 시스템의 관계없는 예외에 묻혀 중앙 오류 보고에서 눈에 띄지 않았다.

    촉발

    Mandrill 의 키 해시 알고리즘이 shard4 에 쓰기를 더 많이 몰아 이 샤드의 autovacuum 이 밀렸거나 실패했고, 2019년 2월 4일 05:35 UTC 에 XID 가 상한에 닿아 데이터베이스가 안전 종료 모드로 들어갔다.

    원인
    구성 요소
    기여 요인
    감지

    첫 예외는 일요일 밤에 로그에 남았지만 다른 시스템의 관계없는 예외에 묻혀 중앙 오류 보고에서 늦게 발견됐다. 11:58 UTC 에 Mandrill 엔지니어가 조사를 시작했고, shard4 의 부하 급증을 쫓다가 12:56 UTC 에 랩어라운드를 찾았다.

    조치
    • 14:16 UTC 에 shard4 를 단일 사용자 모드로 띄우고 VACUUM 을 시작했다.
    • VACUUM 이 며칠 걸릴 것으로 보여 설정을 바꿔 속도를 높인 뒤 다시 시작했다.
    • VACUUM 이 도는 동안 데이터베이스 덤프와 복원을 시작했고, 속도를 높이려고 TB 단위인 Search 와 Url 테이블을 뺐다.
    • 실패한 작업과 로그로 디스크가 모자라자 Mandrill 앱 서버들의 스토리지 볼륨을 교체했다.
    • shard4 에 있던 작업 대기열 테이블을 살아 있는 다른 샤드로 옮겨 작업이 처리되게 하려 했다.
    • 잠긴 데이터베이스에서 테이블을 비우면 그 XID 가 풀린다는 것을 확인한 뒤 2월 5일 19:12 UTC 에 Search 와 Url 테이블을 비웠고, VACUUM 이 약 한 시간 뒤에 끝났다.
    • 21:36 UTC 에 밀린 메일 발송을 시작했다.
    • 22:40 UTC 에 XID 랩어라운드 알림을 새로 걸었다.
    교훈

    Mailchimp 는 대응을 늦춘 요인으로 다섯 가지를 들었다. Mandrill 시스템과 모니터링을 알고 접근할 수 있는 사람이 몇 명뿐이었다. Mandrill 의 로그 기록은 로컬에 쓸 수 있는 디스크에 기댔다. 잘못된 API 요청 로그와 실제 애플리케이션 오류를 구분하기 어려웠다. 작업 상태가 잘 보이지 않았다. 디스크 공간 문제로 원인 분석을 돕는 부분 배포가 위험했다. 잘된 점으로는 인시던트 지휘관을 중심으로 한 긴밀한 조율, 3시간 교대와 인수인계, 기록 담당과 기술 연락 담당 같은 역할 지정, 주기적인 요약과 결정 목록을 들었다. 화상 회의로 다시 모여 상황을 따져 본 것이 테이블을 비우는 해법으로 이어졌다. 대기 메일을 48시간 뒤에 지우는 기본 동작이 다가오자 더 과감한 방법을 검토하게 됐다. Mandrill 이 클라우드에서 돌아 스토리지를 빨리 늘릴 수 있었던 것은 운이었다. 지울 수 있는 데이터가 있었고 그 가운데 VACUUM 을 붙잡던 가장 큰 테이블이 있었던 것도 운이었다.

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

이 4건에서 가장 많이 나오는 구성 요소: 데이터베이스, PostgreSQL vacuum. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별1