Incident Library
적용된 필터 구성 요소데이터베이스 백업과 스냅숏모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

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

사례17건

17건 중 7~11번째

  1. 증상

    하쿠나 서비스의 API latency 가 특정 시간에 주기적으로 치솟았다. APM 의 Dependency 별 Latency 분석에서 병목은 Redis 였다.

    촉발

    가용 메모리가 부족한 상태에서, 하루 한 번 primary 노드에서 도는 ElastiCache 백업이 forkless 방식으로 실행됐다.

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

    특정 시간에 주기적으로 치솟는 API latency 를 그래프에서 보았고, APM 의 Dependency 별 Latency 분석으로 병목이 Redis 임을 알아냈다.

    조치
    • ElastiCache 백업을 primary 노드가 아니라 secondary 노드에서 실행하도록 바꿨다.
    • TTL 없이 저장되던 데이터에 TTL 을 걸어 저장하도록 코드를 고쳤다.
    • Redis Hash CrudRepository 를 쓰던 곳을 RedisTemplate 으로 다시 구현한 CustomRepository 로 바꿨다.
    • 이미 쌓여 있던 필요 없는 데이터를 지우는 스크립트를 실행했다.
    교훈

    백엔드 팀은 Redis 운영과 모니터링에 미흡한 부분이 있었다고 돌아봤다. 데이터 사이에 관계가 있거나 값으로 검색해야 하면 관계형 데이터베이스를 쓰고, 영속성이 필요한 데이터는 되도록 Redis 가 아닌 on-disk 기반 저장소에 둔다. ElastiCache Snapshot 을 만들어야 하면 가용 메모리를 50% 이상으로 유지한다. DEL collection 처럼 O(n) 인 명령 때문에 운영 Redis 가 멈추지 않게 조심한다. 애플리케이션과 데이터베이스 사이에 불필요한 I/O 가 없는지도 주기적으로 확인한다. Spring Data Redis Repository 는 secondary index 를 프레임워크가 관리해 주므로, TTL 이 필요 없고 쿼리 성능이 많이 요구되는 업무에서는 좋은 선택지가 될 수 있다.

  2. 증상

    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 을 돌릴 수 있었다.

  3. 증상

    2019년 12월 어느 금요일 저녁, 내부 모니터링 도구가 시스템에서 5xx 오류가 평소보다 훨씬 많이 난다고 알렸다. SRE 팀은 주요 애플리케이션인 API 가 RDS MySQL 데이터베이스에 접속하지 못한다는 것을 알아챘다. 원인을 파악하기도 전에 애플리케이션이 스스로 살아났고 알림이 멈췄다.

    촉발

    API 애플리케이션의 RDS MySQL 마스터 인스턴스가 Multi-AZ 장애 조치를 거쳐 다른 AZ 의 대기 인스턴스로 넘어갔다.

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

    내부 모니터링 도구가 5xx 오류가 평소보다 훨씬 많다고 알렸다. 복제 실패는 그 뒤 다른 알림으로 왔다. 데이터 손실은 다음 날 데이터베이스와 애플리케이션 트레이스 로그를 맞춰 보다가 찾았다.

    조치
    • 오래된 데이터가 사용자에게 보이지 않도록 복제본으로 가던 트래픽을 모두 마스터 인스턴스로 옮겼다.
    • 새 장비의 전체 스냅샷이 끝나기를 여섯 시간 기다린 뒤 복제본 다섯 대를 다시 만들고 트래픽을 복제본으로 되돌렸다.
    • 바이너리 로그에서 정확한 쿼리를 찾고 애플리케이션 트레이스 로그로 사건 순서를 따라가 8시간 회의 끝에 RDS 에 저장된 데이터를 바로잡았다.
    • 마스터 인스턴스의 innodb_flush_log_at_trx_commit 값을 2 에서 1 로 바꿨다.
    교훈

    잘못 설정한 변수 하나 때문에 Razorpay 는 처음부터 데이터 손실 위험을 안고 있었다. 팀은 장애를 끝까지 파고들어 근본 원인을 찾았고, 그 과정에서 RDS 가 Multi-AZ 구성과 장애 조치를 어떻게 다루는지 많이 배웠다.

  4. 증상

    2018년 10월 21일 22:54 UTC 에 내부 모니터링 시스템이 여러 시스템에서 장애가 났다는 알림을 쏟아내기 시작했다. 23:02 UTC 에 첫 대응 팀은 여러 데이터베이스 클러스터의 토폴로지가 예상하지 못한 상태라는 것을 확인했다.

    촉발

    10월 21일 22:52 UTC 에 고장 난 100G 광 장비를 교체하는 정기 유지보수 작업 중 미국 동부 네트워크 허브와 동부 주 데이터센터 사이의 연결이 끊겼다. 연결은 43초 만에 돌아왔다.

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

    22:54 UTC 에 내부 모니터링 시스템이 알림을 내기 시작해 여러 엔지니어가 알림을 분류했다. 23:02 UTC 에 첫 대응 팀이 Orchestrator API 를 조회해 복제 토폴로지에 서부 데이터센터 서버만 남은 것을 확인했다.

    조치
    • 23:07 UTC 에 내부 배포 도구를 수동으로 잠가 더는 변경이 들어오지 않게 했다.
    • 푸시 같은 메타데이터를 쓰는 작업을 멈추려고 웹훅 전송과 GitHub Pages 빌드를 일시 중지했다.
    • 10월 22일 06:51 UTC 까지 여러 클러스터를 미국 동부 데이터센터에서 백업으로 복원했고, 복원된 서버는 서부에서 새 데이터를 복제받기 시작했다.
    • 외부 저장소에서 내려받는 처리량 한계를 피하려고 서부 데이터센터에서 직접 복원하는 방법을 찾았다.
    • 11:12 UTC 에 모든 데이터베이스 프라이머리를 다시 미국 동부에 세웠다.
    • 미국 동부 퍼블릭 클라우드에 MySQL 읽기 복제본을 추가로 띄워 읽기 요청을 더 많은 서버로 나눴고, 복제본 전체의 사용률이 내려가 복제가 따라잡았다.
    • 복제본이 맞춰진 뒤 16:24 UTC 에 원래 토폴로지로 페일오버했다.
    • 밀린 웹훅 이벤트와 Pages 빌드를 처리했다. 웹훅 페이로드 약 200,000건이 내부 TTL 을 넘겨 버려진 것을 발견하자 처리를 멈추고 TTL 을 당분간 늘리는 변경을 배포했다.
    후속 조치
    • 각 클러스터에서 서부로 복제되지 않은 쓰기를 담은 MySQL 바이너리 로그를 분석해, 자동으로 맞출 수 있는 쓰기와 사용자에게 연락해야 하는 쓰기를 가린다.
    • GitHub Pages 빌드가 멈춘 상황에서도 공지 글을 낼 수 있게 한다.
    • 장애 중 복구 예상 시간을 더 정확하게 알린다.
    • Orchestrator 설정을 고쳐 데이터베이스 프라이머리가 리전 경계를 넘어 승격되지 않게 한다.
    • 녹색, 노란색, 빨간색 세 단계만 있던 상태 표시를 새 상태 보고 방식으로 옮겨 플랫폼 구성 요소마다 상태를 보여 준다.
    • 여러 데이터센터에서 트래픽을 받는 active/active/active 구성으로 옮기는 일을 앞당겨, 시설 단위 N+1 이중화로 데이터센터 하나가 통째로 망가져도 사용자에게 영향이 없게 한다.
    • 시스템이 기대는 가정을 더 적극적으로 시험한다.
    • 장애 시나리오를 사용자에게 닿기 전에 검증하는 관행을 들이고, 장애 주입과 카오스 엔지니어링 도구에 투자한다.
    교훈

    GitHub 은 Orchestrator 가 설정대로 움직였지만 애플리케이션 계층은 그 토폴로지 변경을 견디지 못했다고 봤다. 리전 안의 리더 선출은 대체로 안전하지만, 갑자기 생긴 대륙 간 지연이 이번 장애를 키운 큰 요인이었다. 자동 페일오버 설정은 애플리케이션이 기대하는 것과 맞춰야 한다. GitHub 은 이만큼 복잡한 서비스 체계에서는 운영 통제를 조이거나 대응을 빠르게 하는 것만으로는 안정성을 지킬 수 없다고 판단했다. 그래서 가정을 더 적극적으로 시험하고, 장애 시나리오를 사용자에게 닿기 전에 검증하기로 했다. 복구 예상 시간은 모든 변수를 고려하지 못해 틀렸다.

  5. 증상

    2017-04-05 10:24 EDT 에 공개 서비스가 동작하지 않는다는 알림이 들어왔다. 제어판과 API 를 쓸 수 없었다. 돌고 있던 Droplet 은 계속 동작했지만, 새 Droplet 이나 다른 자원을 만들거나 관리할 수는 없었다.

    촉발

    자동 테스트를 돌리는 프로세스가 운영 환경 자격 증명을 쓰도록 잘못 설정돼 있었고, 그 결과 주 데이터베이스가 지워졌다.

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

    10:24 EDT 에 공개 서비스가 동작하지 않는다는 알림이 들어왔고, 3분 뒤 마스터의 운영 데이터베이스가 지워진 것을 확인했다.

    조치
    • 10:34 EDT 에 시간 지연 레플리카에서 복구를 시작했다.
    • 11:53 에 시간 지연 레플리카의 백업을 마쳤다.
    • 12:34 에 백업을 마스터로 복사하고 복원을 시작했다.
    • 13:31 에 마스터 복구를 마쳤고 레플리카로 백업을 복사하는 일을 이어 갔다. 15:20 에 모든 시스템이 복원됐다.
    후속 조치
    • 같은 일이 다시 없도록 특정 작업에서 주 시스템에 접근할 수 있는 권한을 크게 줄인다.
    • 데이터베이스 서버 사이의 네트워크 연결을 업그레이드한다.
    • 복구 속도를 높이도록 하드웨어를 바꾼다.
    • 개발자 실수를 막는 안전장치를 더 검토한다.
    • 데이터 복구 절차를 개선한다.
    • 고객에게 영향을 주는 장애가 날 때 실시간 정보를 더 잘 전할 방법을 찾는다.
내 클러스터에도 있는지 확인하기

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

원인별8

용량 한계3건

  1. IL-0309 RDS PostgreSQL 메이저 버전 업그레이드가 점검 시간을 훨씬 넘겨 실패하면서 us2a 배포가 약 6시간 멈췄다
    Preset2026
  2. IL-0453 하쿠나의 API latency 가 매일 ElastiCache Redis 백업 시간마다 치솟았다
  3. IL-0334 RDS MySQL 의 bookmarks 테이블이 2TB 파일 크기 한도에 닿아 INSERT 가 실패하고 Instapaper 가 31시간 동안 멈췄다

소프트웨어 결함2건

  1. IL-0281 PostHog US 리전 Logs 제품의 ClickHouse 클러스터가 S3 에 둔 로그 데이터를 거의 다 지워 3일보다 오래된 로그가 사라졌다
  2. IL-0485 계획된 OS 업그레이드 작업이 운영 중인 데이터베이스 서버를 재설치해 Dropbox 서비스가 멈췄다

배포 결함2건

  1. IL-0380 AWS us-east-1 의 InfluxDB Cloud 클러스터에서 압축 중에 일부 데이터가 빠져 쿼리에 나오지 않았다
  2. IL-0371 PITR 을 켠 Render Postgres 데이터베이스에서 백업이 도는 동안 새 연결의 절반이 실패했다
    Render2023

업그레이드로 깨진 호환성1건

조직
  1. IL-0484 Slurm 업그레이드 뒤 GPU 설정이 맞지 않고 다운그레이드도 실패해 MIT CSAIL 공용 GPU 클러스터가 수요일 아침까지 멈췄다

운영 실수5건

  1. IL-0242 primary 와 secondary PostgreSQL 데이터베이스를 모두 잃어 matrix.org homeserver 가 약 24시간 동안 멈췄다
  2. IL-0218 복제를 다시 맞추다 PostgreSQL 프라이머리의 데이터 디렉터리가 지워지고 백업이 작동하지 않아 GitLab.com 이 약 18시간 멈추고 데이터를 잃었다
    GitLab2017
  3. IL-0573 개발자의 실수로 MariaDB 빌링 데이터베이스의 주요 테이블 9개가 DROP되어 배달의민족 결제가 잠시 멈췄다
  4. IL-0319 mysql2 를 다시 적재하려고 데이터베이스를 지우는 동안 mysql1 의 데이터베이스도 함께 지워졌다
  5. IL-0538 사쿠라 클라우드 스토리지의 일괄 삭제 작업이 고객이 쓰던 디스크 53개를 지웠고 되살리지 못했다

데이터 손상1건

  1. IL-0311 주 PostgreSQL 데이터베이스가 트랜잭션 ID wraparound 보호로 읽기 전용이 되어 웹사이트와 백엔드 서비스가 멈췄다

설정 변경2건

  1. IL-0331 RDS MySQL Multi-AZ 장애 조치 뒤 읽기 복제본 다섯 대의 복제가 모두 깨지고 데이터 5초 분량이 사라졌다
  2. IL-0325 주 데이터베이스가 지워져 DigitalOcean 제어판과 API 가 4시간 56분 동안 멈췄다

DNS·네트워크 장애1건

조직
  1. IL-0210 43초 네트워크 단절 뒤 MySQL 프라이머리가 미국 서부로 넘어가 GitHub.com 이 24시간 11분 동안 느려지고 오래된 데이터를 보여 줬다
    GitHub2018