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

그래프

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

사례10건

10건 중 1~5번째

  1. 증상

    learn.mit.edu 가 멈췄다는 보고가 Sentry 이슈 링크와 함께 올라왔다. MIT Learn 의 운영 데이터베이스인 RDS PostgreSQL 인스턴스가 쓸 수 있는 저장 공간을 모두 써 버린 상태였고, 사이트는 503 과 504 오류를 냈다.

    촉발

    정기 릴리스 절차로 배포한 변경이 페이지 응답의 메인 쿼리 안에 집계를 넣었다. DRF 는 페이지 응답의 count 칸을 SELECT COUNT * ($QUERY) 로 계산하므로, 운영의 데이터 규모에서 이 쿼리가 임시 파일을 대량으로 만들었다.

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

    엔지니어가 장애를 보고하며 Sentry 이슈를 연결했다. 이어 다른 엔지니어가 운영 데이터베이스의 저장 공간이 바닥난 것을 확인했고, FreeStorageSpace 지표와 Sentry 에 쌓인 504 도 같은 상황을 보여 줬다.

    조치
    • 쿼리 패턴 변경을 쓴 엔지니어가 그 변경이 원인임을 확인하고 릴리스를 롤백했다.
    • 데이터베이스가 버퍼에 쌓인 WAL 파일을 따라잡아 비울 여유를 주려고 읽기 복제본을 삭제했다.
    • AWS 지원의 도움을 받아 백업이 끝난 뒤 오래 돌던 쿼리를 안전하게 종료했다. pg_stat_activity 에서 state = 'active' 이고 시작한 지 10분이 넘은 쿼리를 pg_terminate_backend(pid) 로 끝내자 저장 공간과 처리 여유가 돌아왔다.
    후속 조치
    • 운영 learn 데이터베이스에 enhanced analytics 를 켜는 방안을 검토한다.
    • 플랫폼 엔지니어링 문서 사이트에 롤백 절차를 적는다.
    • 장기적으로는 새로 만드는 릴리스 관리 체계에서 롤백을 쉽게 할 수 있게 한다.
    • 운영 데이터베이스의 DiskQueueDepth 에 알림을 걸되 너무 자주 울리지 않게 한다.
    • API 와 사이트의 응답 시간이 평소보다 30% 넘게 높아지면 알림을 보낸다.
    • 운영 데이터베이스 장애를 예제로 삼아 게임데이 훈련을 한다.
    • 장애 관리 도구 Rootly 를 써서 장애 때 소통을 한 채널에 자동으로 모으고 장애 기록을 자동으로 남긴다.
    • 장애 대응 런북을 가볍게 만든다. 장애가 나면 Zoom 통화를 열고, 당번 엔지니어가 지표가 평소 수준으로 돌아오는지 지켜보며, 소통 담당을 따로 두어 이해관계자의 문의가 핵심 대응자를 방해하지 않게 한다.
    • 오래 도는 쿼리를 종료하는 SQL 과, 이 SQL 을 고쳐 아주 오래 도는 쿼리만 골라 종료하는 SQL 을 운영 Postgres 런북에 넣는다.
    • Learn Resource View Event 모델이 지금은 건수를 세는 데만 쓰이므로 다시 설계해야 한다는 이슈를 쓴다.
    • 익명화한 운영 데이터 생성 도구로 RC 환경의 데이터 양을 운영 수준까지 늘린다. 운영 데이터를 익명화해 담은 운영 규모의 부하 시험 환경을 만들고, 이해관계자도 시험에 쓰는 RC 에 영향이 없도록 인프라를 분리한다.
    • 조회 수를 미리 계산해 둔 열에서 읽도록 고쳐 배포했다. 영향을 받던 API 의 운영 응답 시간이 약 13~15초에서 150~200ms 로 줄었다.
    교훈

    이 변경은 가장 시니어인 엔지니어 두 명이 꼼꼼히 리뷰했지만 로컬과 RC 환경에서는 아무 문제도 드러나지 않았다. 운영의 데이터 규모와 시스템 부하가 크게 달랐고, 효율적이라고 여긴 COUNT 집계가 디스크 사용량을 폭증시킬 것이라는 점은 당시 시스템 상태만 보고는 알기 어려웠다. 그래서 운영과 같은 규모의 데이터로 부하를 시험할 환경이 필요하다고 팀은 결론지었다. AWS 지원은 ORM 쿼리 변경을 운영 수준의 데이터를 담은 스테이징에서 시험하고, EXPLAIN ANALYZE 로 실행 계획과 예상 자원 사용을 보며, 시험 중 log_temp_files 로 임시 파일 생성을 지켜보라고 권했다. 폭주하는 쿼리를 막도록 temp_file_limit 를 설정하고, 실행 계획에 따라 work_mem 이나 shared_buffers 를 조정하되 메모리를 너무 쓰면 out of memory 로 장애 조치가 일어날 수 있다는 점도 짚었다. 임시 파일을 많이 쓰는 작업에는 임시 파일을 EBS 대신 로컬 NVMe 에 두는 RDS Optimized Reads 를 고려하라고 했다.

  2. 증상

    2026-02-19 8:11 AM PST 에 데이터베이스 성능이 갑자기 떨어졌다. 요청 핸들러에 요청이 쌓였고, Clerk 트래픽의 95% 넘게 처리되지 못한 채 429 를 받았다. 데이터베이스까지 간 일부 요청은 200 을 받았지만 아주 느렸다.

    촉발

    Postgres 의 일상적인 자동 ANALYZE 가 표본을 너무 적게 뽑아 한 컬럼의 값이 100% NULL 이라고 잘못 판단했다. 그 결과 자주 실행되는 쿼리의 플랜이 비효율적인 것으로 바뀌었다.

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

    16:15 UTC 에 사고가 내부에 보고되고 에스컬레이션됐고, 팀이 그룹 통화를 열어 근본 원인을 찾기 시작했다.

    조치
    • 17:08 UTC 에 핵심 Session API 밖에서 세션 토큰을 만드는 새 장애 조치를 켜서 백엔드 부하를 줄였고, 17:10 UTC 에 많은 사용자가 고객 앱에 다시 들어갔다.
    • 17:27 UTC 에 해당 테이블에 ANALYZE 를 수동으로 다시 돌렸고, 쿼리가 이전 플랜으로 돌아가 데이터베이스가 회복하기 시작했다.
    • 17:43 UTC 에 시스템이 안정되고 데이터베이스가 정상 수준으로 돌아오자 새 장애 조치를 껐다.
    • 사고 직후 해당 테이블의 statistics target 을 올려 쿼리 플래너가 더 크고 정확한 표본을 보게 했다.
    • 그날 저녁 플래너가 결정론적인 플랜을 세울 수 있게 쿼리를 다시 짰다.
    후속 조치
    • 데이터베이스 쿼리 플랜이 바뀌는 것을 잡는 전용 알림을 더한다.
    • 안정성 팀이 새 세션 토큰 장애 조치를 켜는 방법을 익히게 하고, 자동 작동 조건을 건다. 몇 주 안에 끝내는 것이 목표다.
    • 불안정한 통계로 비효율적인 플랜이 생길 위험이 있는 쿼리가 더 있는지 모든 쿼리를 점검한다.
    • 사고 때 소통 전담자를 둔다.
    • 상황이 그대로여도 정해진 간격으로 상태 페이지를 갱신한다.
    • 상태 페이지의 심각도 표시가 고객이 겪는 영향과 맞게 한다.
    • 사고 도구를 고쳐 공지가 소셜 채널에도 함께 올라가게 한다.
    교훈

    Clerk 는 쿼리 플랜이 바뀌는 문제가 갑자기 심하게 성능을 떨어뜨리므로, 뒤따르는 증상에 기대지 말고 바로 잡아내야 한다고 보았다. 이런 알림이 있었다면 고객의 트래픽 패턴이 원인이라고 잘못 보는 일을 피할 수 있었다. 데이터베이스가 내려가지 않고 느려지기만 하자 Postgres 장애를 기준으로 만든 Session API 의 자동 장애 조치는 작동하지 않았다. 고객들은 상태 페이지 공지가 너무 드물고, 첫 심각도 표시가 실제 영향과 맞지 않았으며, 첫 공지까지 시간이 너무 걸렸다고 지적했다.

  3. 증상

    MongoDB Atlas 와 Cloud Manager 에서 지표 수집 파이프라인이 늦어졌고, Atlas 대시보드의 지표가 늦거나 빠졌다. Host Down 알림이 울리지 않았고, 프로비저닝과 크기 조정 같은 Atlas 클러스터 관리 작업이 늦어졌다.

    촉발

    새 내부 소프트웨어 버전을 롤아웃하는 동안 자원 사용량이 일시적으로 치솟아, 이미 부하가 몰려 있던 샤드의 부하가 예상한 한도를 넘었다.

    원인
    구성 요소
    기여 요인
    조치
    • 원인을 찾아 바로잡는 조치를 하고 그 효과를 지켜봤다. 그동안 Host Down 알림, 지표, 일부 Atlas 클러스터 작업은 계속 늦거나 빠질 수 있었다.
    • 수정을 적용하고 결과를 지켜봤으며, 이후 장애가 해결됐다.
    후속 조치
    • 부하가 몰리는 컬렉션을 샤딩해 트래픽을 여러 노드에 고르게 나누고 샤드 하나에 몰리는 부하를 던다.
    • 비효율적인 쿼리를 최적화해 자원 사용을 개선하고 평소 작업의 지연을 줄인다.
    • 늘어난 트래픽을 감당하도록 인프라 용량을 더 확보했다.
    • 앞으로의 부하 급증을 미리 내다보도록 용량 계획 절차를 다듬는다.
    • 롤아웃 중 예상할 수 있는 자원 수요 증가를 감안하도록 새 소프트웨어 버전 배포 절차를 다시 설계한다.
    • 엔지니어링 팀이 샤딩 전략과 쿼리 최적화의 성능을 계속 지켜보며 핫스팟이 제대로 풀렸는지 확인한다.
    • 높은 부하 상태를 감지하는 피드백 장치를 넓혀 이상을 더 빨리 찾고 대응한다.
  4. 증상

    2025년 5월 8일 15시 26분 UTC부터 Bitbucket Cloud 웹사이트와 API의 응답이 느려졌다. 주 데이터베이스가 과부하에 걸려 있었다.

    촉발

    Atlassian 내부 서비스가 돌린 대규모 백필 작업이 일부 API 엔드포인트에 과도한 부하를 걸었고, 그 엔드포인트들이 비용이 큰 쿼리를 주 데이터베이스에 대량으로 보냈다.

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

    실시간 모니터링이 장애를 바로 감지했다. 상태 페이지에는 15시 41분 UTC에 조사 중이라는 공지가 올라왔다.

    조치
    • 부하가 큰 백필 작업을 멈췄다.
    • 주 데이터베이스가 자동으로 장애 조치됐고, Bitbucket 서비스가 15분 만에 회복했다.
    • 장애 조치 뒤 엔지니어링 팀이 데이터베이스 부하를 더 덜어 내는 여러 방법을 적용해 자원 압박을 줄이고 성능을 끌어올렸다.
    후속 조치
    • 데이터베이스 요청 라우팅을 고쳐, 읽기 요청을 쓰기용 주 데이터베이스 대신 읽기 복제본으로 더 많이 보낸다.
    • 자원을 많이 쓰는 데이터베이스 작업을 하는 내부 API 엔드포인트의 속도 제한을 조정한다.
    • 데이터베이스 쿼리가 더 효율적으로 돌도록 최적화한다.
    • 하위 서비스들의 재시도 정책을 조정한다.
  5. 증상

    스마트리스트 프리셋 데이터를 고쳐 쓰는 배치를 20분쯤 돌린 시점에 504 Gateway Timeout 에러가 갑자기 늘었다는 알림이 왔다. 작업은 03:00 UTC 조금 넘어 시작했다.

    촉발

    검색 사양 변경에 맞춰 스마트리스트 프리셋 데이터인 初回予約の顧客 와 要フォロー顧客 의 검색 조건을 새 조건으로 고쳐 쓰는 배치를 실행했다. 프리셋 이름은 그대로였지만 검색 파라미터가 달라져 새 검색 쿼리를 타게 됐다.

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

    고쳐 쓰기 배치를 시작하고 20분쯤 지나 504 에러가 늘었다는 알림으로 알았다. 작업 중 보던 라이터 인스턴스 지표에는 변화가 없었다.

    후속 조치
    • DB 설계부터 다시 봤고, 이번 글의 인라인 뷰 검색 로직은 더 이상 쓰지 않는다.
    • 이 API의 EXPLAIN을 확인해 훑는 행 수가 예상보다 많지 않은지 검사하는 테스트를 더했다.
    • 해당 로직의 실제 실행 시간을 재기 쉬운 환경을 갖췄다.
    교훈

    실행 계획을 보고 실제 데이터로 동작을 확인해도, 멀티테넌트 환경에서는 테넌트 인덱스만으로 크게 좁혀지는 것처럼 보여 실제로 훑는 양을 놓칠 수 있다. 검증은 양극단만이 아니라 일부만 느린 경우까지 봐야 한다. 작업 중 모니터링하는 대상이 실제 부하가 걸리는 곳인지도 확인해야 한다. 일정을 너무 서두르면 이런 부분이 빠지기 쉽고, 결국 일정이 늦어지고 사용자에게 피해를 준다.

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

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

원인별3

배포 결함3건

  1. IL-0510 MIT Learn 운영 RDS PostgreSQL 의 저장 공간이 임시 파일로 가득 차 learn.mit.edu 가 세 시간 동안 503 과 504 를 냈다
  2. IL-0571 STORES 予約의 스마트리스트 검색 쿼리가 특정 테넌트에서 20분 넘게 DB 프로세스를 붙잡아 504 에러가 급증했다
    STORES2024
  3. IL-0567 쿠키런: 오븐브레이크의 패키지 매출 랭킹 기능을 배포한 뒤 Aurora MySQL CPU가 100%에 이르러 유저가 게임에 접속하지 못했다

쿼리 실행 계획 변경1건

조직
  1. IL-0317 Postgres 쿼리 플랜이 바뀌어 데이터베이스가 느려지고 Clerk 트래픽의 95% 넘게 429 를 받았다
    Clerk2026

용량 한계6건

  1. IL-0287 Atlas 와 Cloud Manager 의 모니터링을 받치는 내부 데이터베이스 클러스터의 샤드 하나가 과부하되어 지표 수집과 클러스터 작업이 늦어졌다
  2. IL-0551 Bitbucket Cloud 주 데이터베이스가 과부하로 장애 조치된 뒤 하루 가까이 지연과 간헐 오류가 이어졌다
  3. IL-0447 RDS MySQL 인스턴스의 EBS BurstBalance 가 바닥나 IOPS 가 기준 성능으로 묶이고 데이터베이스 성능이 크게 떨어졌다
    every2024
  4. IL-0302 GitHub 의 공용 MySQL 클러스터 mysql1 이 최대 부하 시간대에 연결이 바닥나 쓰기 작업이 네 번 멈췄다
    GitHub2022
  5. IL-0212 캐시 적중률이 떨어지며 채널 멤버십 Vitess 키스페이스가 과부하에 빠져 많은 사용자가 Slack 에 접속하지 못했다
    Slack2022
  6. IL-0456 100% 할인 이벤트 기간에 인프런 서비스가 Aurora PostgreSQL 병목으로 여섯 번 멈췄다
    Inflab2022