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

그래프

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

사례10건

10건 중 6~10번째

  1. 증상

    2022년 11월 23일 9:39 UTC 에 트래픽 전부가 새 Aurora PostgreSQL 14.x 클러스터로 넘어갔고, 지연이 나빠져 인프라 팀이 조사를 시작했다. 9:54 UTC 에는 쿼리가 평소보다 훨씬 오래 걸리면서 데이터베이스 연결을 모두 차지하고 있었다.

    촉발

    복제를 이용해 Aurora PostgreSQL 10.x 클러스터에서 새 14.x 클러스터로 트래픽을 넘겼다. 그런데 가장 큰 테이블 하나의 vacuum 이 전환 전에 끝나지 않아, 새 클러스터의 가장 큰 테이블들에 ANALYZE 가 돌지 않은 상태였다.

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

    9:39 UTC 에 트래픽 전부가 새 클러스터로 넘어갔을 때 지연이 나빠 보였고, 인프라 팀이 바로 조사를 시작했다.

    조치
    • 9:54 UTC 에 쿼리가 데이터베이스 연결을 너무 오래 잡지 않도록 데이터베이스 사용자에 statement timeout 을 걸었다.
    • 9:58 UTC 에 로드 밸런서에서 트래픽의 90% 에 503 을 보내 부하를 덜고 시스템이 회복할 여유를 만들었다.
    • 10:00 UTC 무렵부터 오래 걸리는 쿼리에 EXPLAIN 을 돌려 보고, 해만 끼치고 필요 없는 인덱스를 지우기 시작했다.
    • 트래픽을 100% 로 되돌리는 동안 Apple 웹훅을 잠시 받지 않았다.
    • New Relic 이 느린 쿼리마다 돌리는 EXPLAIN 쿼리를 없애려고 New Relic 을 끈 새 릴리스를 냈다.
    • 12:00 UTC 무렵부터 가장 큰 테이블들에 손으로 ANALYZE 를 돌렸다.
    • 미리 준비해 둔 스크립트로 영향받은 시퀀스 값을 자동으로 올려 기본 키 중복을 풀었다.
    • 전환 몇 분 뒤 통합 이벤트 발송 작업이 이벤트 테이블을 갱신하지 못하는 것을 잡고 발송 작업을 손으로 멈췄다.
    • 발송되었지만 데이터베이스에 기록되지 않은 웹훅을 만일에 대비해 다시 보냈다.
    • 13:33 UTC 에 통합 이벤트 발송, ETL, 웹 서버 밖의 작업을 모두 되살렸다.
    후속 조치
    • 사업에 중요한 시기에는 변경 동결을 두는 것을 검토한다.
    • 백엔드 장애 때 SDK 가 얼마나 믿을 만하게 동작하는지 더 잘 알린다.
    • 개발자 대시보드와 기술 담당자에게 보내는 직접 이메일을 써서 유지보수와 장애를 고객에게 더 잘 알린다.
    • 사전 연습에서 트래픽 일부를 재생해 전환 당일과 더 비슷한 조건을 만든다. 이번 연습은 쓰기 트래픽을 재생하지 않았다.
    • API 를 빠르고 안정적으로 유지하려고 비용이 큰 작업을 최대한 비동기로 옮기는 데 더 투자한다.
    • 테이블 인덱스를 다시 검토한다. 쓰이지 않는 인덱스가 있고, 데이터베이스가 쿼리에 그 인덱스를 고르면 성능이 떨어질 수 있다.
    • 데이터베이스 대시보드에서 엔드포인트와 시스템별 부하를 더 잘 보여 줘 부하가 어디서 오는지 빨리 찾게 한다. 이번에는 Apple 웹훅 부하가 복구를 막는다는 것을 아는 데 너무 오래 걸렸다.
    • 장애 중에 고객 지원과 고객 커뮤니케이션 담당을 불러 소통을 맡긴다.
    교훈

    RevenueCat 은 처음부터 롤백했으면 더 나았다고 돌아봤다. 사전 연습에서는 데이터 일관성과 쿼리 성능만 보고 쓰기 트래픽을 재생하지 않았다. 쓰기는 인덱스가 얽히지 않아 읽기보다 단순하다고 여겼기 때문이다. 복제를 멈추고 평소처럼 쓰기를 해 봤다면 문제를 찾을 수 있었다. 시퀀스 상태가 복제되지 않는다는 한계를 놓치고 상태도 함께 복제된다고 가정했다. 사전 연습 때는 새 클러스터가 오래 떠 있어 vacuum 과 통계가 이미 끝나 있었기 때문에 ANALYZE 가 없는 문제를 보지 못했다. 시기로는 추수감사절과 블랙 프라이데이 전에 끝내려 했지만, 미국 지원팀 일부가 이미 휴가 중인 민감한 때였으므로 그다음 주로 미뤘어야 했다고 밝혔다.

  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. 증상

    Aurora MySQL 의 reader 가 이유를 알 수 없이 재시작했다. 그 직후부터 writer 의 insert latency 가 7배쯤 오르는 등 writer 성능이 크게 떨어진 상태가 오래 이어졌다. 같은 일이 2019년 11월 두 주 사이에 두 번 일어났다.

    촉발

    reader 에서 오래 도는 쿼리 때문에 롤백 세그먼트가 계속 커진 끝에 reader 가 재시작했다. 글쓴이는 그 쿼리가 Redash 에서 reader 로 보낸 것이었다고 기억한다.

    원인
    구성 요소
    기여 요인
    조치
    • 팀은 writer 성능이 원래대로 돌아올 때까지 지켜보기만 했다.
    후속 조치
    • 롤백 세그먼트 길이를 Datadog 의 mysql.innodb.history_list_length 로 감시하는 모니터를 더했다.
    • reader 가 재시작할 만큼 오래 도는 쿼리를 찾으면 바로 kill 하게 했다.
    • 모니터 알림이 거의 매주 울리게 되자 사내에 알린 뒤 max_execution_time 을 설정해, 일정 시간이 지난 쿼리를 강제로 끝내게 했다.
    교훈

    롤백 세그먼트가 커지지 않도록 트랜잭션을 작게 해야 한다. 롤백 세그먼트는 클러스터 전체가 함께 쓰므로, 한번 커지면 인스턴스를 바꿔도 해제가 끝나기를 기다리는 수밖에 없다. 롤백 세그먼트 길이는 show engine innodb status 의 "History list length" 값으로 볼 수 있다.

  4. 증상

    2월 9일 수요일 12:30PM PT 부터 Instapaper 사용자가 저장한 글을 담는 MySQL 의 bookmarks 테이블에 새 항목을 넣으면 오류가 나기 시작했다. Instapaper 서비스는 2월 10일 목요일 7:30pm PT 까지 멈췄다.

    촉발

    2월 9일 수요일 12:30PM PT 에 bookmarks 테이블이 2TB 파일 크기 한도를 넘었다.

    원인
    구성 요소
    기여 요인
    조치
    • Pinterest SRE 팀의 안내로 Instapaper 운영 데이터베이스를 i2.8xlarge 인스턴스의 5.5TB RAID-0 디스크에 덤프했다. 첫 시도는 24시간, 병렬로 돌린 두 번째 시도는 10시간이 걸렸다.
    • 덤프가 너무 오래 걸리자 아카이브 접근을 제한한 채 동작하는 인스턴스를 약 6시간 만에 만들어, 31시간의 다운타임 끝에 운영에 올렸다.
    • 옛 데이터베이스의 Aurora 읽기 복제본을 만들었다. Aurora 는 Instapaper 코드로 충분히 시험해 보지 않아 위험하다고 봤지만 만들기는 쉬웠다. 약 24시간 만에 끝났다.
    • 새 MySQL RDS 인스턴스를 만들어 보조 인덱스 없이 데이터를 모두 넣었다. 8시간이 걸렸다. 그 뒤 보조 인덱스 세 개를 하나에 약 16시간씩 만들었다.
    • Amazon 엔지니어가 실패한 운영 데이터베이스에 ext4 파일 시스템을 마운트하고 ext3 파일 시스템에서 ext4 파일 시스템으로 rsync 를 약 8시간 돌려, 데이터와 인덱스가 모두 있는 ext4 데이터베이스 인스턴스를 만들었다.
    • RDS 엔지니어들이 임시 운영 데이터베이스의 바이너리 로그로 새 ext4 데이터베이스에 행 기반 복제를 걸어 목요일부터 월요일까지의 변경을 맞췄다. 약 3시간이 걸렸다.
    • 새 데이터베이스를 마스터로 승격하고 애플리케이션 코드가 새 데이터베이스를 가리키도록 배포했다.
    후속 조치
    • Instapaper 전체 장애가 나면 Pinterest 의 SRE 팀에 바로 에스컬레이션하는 절차를 만든다.
    • MySQL 백업 시험 주기를 석 달에 한 번에서 한 달에 한 번으로 늘린다.
    • Pinterest 의 SRE 팀과 함께 이런 장애가 다시 나면 복구할 수 있는 절차를 마련한다.
    교훈

    팀이 알지 못했고 볼 수도 없었던 파일 시스템 한도 때문에 운영 데이터베이스뿐 아니라 모든 백업까지 쓸 수 없게 됐다. 호스팅된 인스턴스에는 MySQL 로만 접근할 수 있어서 rsync 같은 파일 시스템 수준의 해결책은 Amazon 엔지니어의 도움 없이는 쓸 수 없었다. 완벽하게 대응했어도 진단부터 데이터베이스 재구축까지 다운타임은 최소 10시간이었을 것이다. 이 문제는 미리 내다보고 막기 어려웠지만, 이런 장애를 위한 재해 복구 계획이 없어 다운타임과 복구 시간이 필요 이상으로 길어졌다. 데이터베이스를 다시 만드는 데 며칠이 걸린다는 것을 알았다면 곧바로 제한된 서비스 복구로 들어가 첫날의 다운타임을 크게 줄일 수 있었다. Pinterest 안에서, 그리고 AWS 팀과 더 잘 소통했다면 쓸 수 있는 자원을 더 잘 활용했을 것이다. 글쓴이는 다른 회사가 호스팅하는 기술이라도 매일 운영에 쓰는 기술의 한도를 이해하는 것이 자신의 책임이라고 밝혔다.

  5. 증상

    WORKER_JOB_ERROR 오류가 늘었다는 신고가 들어왔다. 이 오류는 파일을 받아 Assembly 를 조율하는 Uploader 와 인코딩을 실행하는 Drone 사이의 통신에 문제가 있다는 뜻이다.

    촉발

    HLS 트래픽이 가파르게 늘었고, 같은 양을 더 빨리 처리하려고 Drone 을 더 많이 띄울 수 있게 되면서 중앙 노드가 바빠졌다. 이를 설명할 코드나 인프라 변경은 찾지 못했고, 이 두 변화가 겹쳐 Redis 병목이 드러났다.

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

    WORKER_JOB_ERROR 오류가 늘었다는 신고가 들어와 문제를 알았다. 모니터링은 Redis 명령 수, 연결 수, 스왑 사용량을 보고 있었지만 대역폭은 보지 않아 포화를 잡지 못했다.

    조치
    • 잃은 메시지를 다시 넣고 하트비트 감시를 느슨하게 하는 임시 조치를 했다. 증상만 막는 조치였고 Assembly 실행 시간이 늘었다.
    • 놓친 Redis 패치가 있는지 확인하고 Redis 를 최신 안정 버전으로 올렸다.
    • 대역폭 제한에 걸린 것을 알고 Redis 클러스터를 두 배인 여섯 대로 늘렸다. 곧 다시 포화되자 세 대를 더 붙였지만 상황은 더 나빠졌다.
    • 읽기 replica 를 하나로 줄였다. 트래픽과 실패율이 바로 떨어졌고 Assembly 가 다시 빨라졌다.
    • 리전마다 Drone 확장에 상한을 두었다. 큰 배치 가져오기는 시간이 더 걸릴 수 있지만 시스템은 안정을 유지한다고 밝혔다.
    후속 조치
    • 포화 수준에 다시 가까워지면 알 수 있도록 로그와 알림을 더 둔다.
    • Redis 노드와 Drone, Uploader 사이의 트래픽을 한곳에 몰리지 않게 나눌 방법을 찾는다.
    • 이미 하고 있는 리전별 샤딩에 더해 Uploader 별 샤딩을 추가한다.
    교훈

    Redis 노드를 늘린 것은 잘못된 판단이었다. 모든 쓰기를 리더 한 대가 받는 구조에서는 노드가 늘수록 리더가 복제로 내보낼 트래픽이 늘어, 더 많은 트래픽을 감당하려면 노드를 오히려 줄여야 했다. 잃은 데이터를 다시 넣을 수 있으므로 팀은 복제가 꼭 필요한지 다시 따져 봤다. 지표는 이미 많이 지켜보고 있었지만 알림을 제대로 걸 수 있는 지표는 몇 개뿐이어서, 고른 지표가 모자랐을 수 있다. 대역폭도 빠져 있었다. 쓰기를 받는 Redis 노드가 하나뿐이면 replica 를 줄이거나 노드를 키워도 시간을 조금 벌 뿐이고, 성장을 버티려면 트래픽을 나눠야 한다.

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

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

원인별6

용량 한계5건

  1. IL-0379 Azure West Europe 의 InfluxDB Cloud 에서 9월 27일부터 30일까지 쿼리가 느려지고 타임아웃됐다
  2. IL-0288 CDN77 의 ClickHouse 데이터 파이프라인에서 이중화된 인스턴스 세 곳의 ZooKeeperWait 가 수천 초로 치솟아 복제가 한 시간 넘게 느려졌다
    CDN772026
  3. IL-0443 Aurora MySQL reader 가 이유 없이 재시작한 뒤 writer 의 insert latency 가 7배쯤 오르고 replication lag 가 하루 넘게 이어졌다
    Repro2019
  4. IL-0334 RDS MySQL 의 bookmarks 테이블이 2TB 파일 크기 한도에 닿아 INSERT 가 실패하고 Instapaper 가 31시간 동안 멈췄다
  5. IL-0296 Transloadit 의 us-east 리전 Redis 클러스터가 대역폭에 막혀 작업과 하트비트를 잃었다

인증서·자격 증명 만료1건

  1. IL-0490 관리형 데이터베이스에서 자체 MySQL로 옮긴 뒤 이전 직전에 쓴 기록이 새 데이터베이스에 없어 LootLocker 서비스가 저하됐다

소프트웨어 결함1건

조직
  1. IL-0281 PostHog US 리전 Logs 제품의 ClickHouse 클러스터가 S3 에 둔 로그 데이터를 거의 다 지워 3일보다 오래된 로그가 사라졌다

설정 변경1건

  1. IL-0392 데이터센터 전환을 앞두고 원형 복제를 설정하던 중 Wikimedia x1 섹션의 eqiad·codfw 사이 MariaDB 복제가 6분 멈췄다

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

  1. IL-0308 RevenueCat 이 Aurora PostgreSQL 10 에서 14 새 클러스터로 넘어간 직후 쿼리가 극도로 느려져 대시보드와 SDK 엔드포인트가 세 시간 넘게 실패했다

데이터 손상1건

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