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

그래프

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

사례13건

13건 중 1~5번째

  1. 증상

    운영 환경의 엔드포인트를 RDS Proxy로 바꾸고 몇 분 뒤 사내 알림 모니터링 시스템에서 에러 알림이 울렸다. Aurora writer의 CPU 사용률은 거의 100%에서 내려오지 않았다.

    촉발

    운영 환경의 Aurora MySQL 접속 엔드포인트를 RDS Proxy로 바꿨다. Proxy는 MaxConnectionsPercent 21%로 Aurora에 커넥션을 약 3,360개만 열 수 있었고, ConnectionBorrowTimeout은 애플리케이션 소켓 타임아웃과 같은 7초였다.

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

    운영 환경의 엔드포인트를 RDS Proxy로 바꾸고 몇 분 뒤 사내 알림 모니터링 시스템이 에러 알림을 냈다.

    조치
    • 그 자리에서 되돌리기로 하고, RDS Proxy를 보는 애플리케이션 서버인 ECS Fargate 태스크를 이전 버전으로 되돌렸다.
    후속 조치
    • 검증 환경에서 설정 값만으로 장애가 재현되고 해소되는 것을 확인한 뒤 MaxConnectionsPercent를 62%로, MaxIdleConnectionsPercent를 31%로 바꿨다.
    • 애플리케이션 안에서 피처 플래그를 평가해 Aurora 직결과 Proxy 경유 중 어디로 접속할지 요청마다 정하게 했다. 플래그는 ECS 태스크 ID의 해시로 태스크 단위로 나눠 한 태스크 안에서 접속 대상이 섞이지 않게 했다.
    • 트랜잭션 중간에 커넥션이 끊길 때 영향이 큰 쓰기 요청은 뒤로 미루고, 조회용 GET 요청부터 옮긴다.
    • 옮기는 비율은 1%, 10%, 25%, 50%, 75%, 100%로 단계적으로 올린다. 단계마다 Proxy의 대기 시간과 새 백엔드 커넥션 수, Aurora의 커넥션 수와 CPU와 지연, 애플리케이션 에러 수를 보고 다음 단계로 간다.
    교훈

    이번 장애와 이후의 문제는 RDS Proxy의 버그가 아니었고, Proxy를 끼우면서 애플리케이션 커넥션 풀의 구현과 설정에 있던 문제가 드러난 것이었다. Proxy를 끼우면 백엔드 커넥션을 여러 클라이언트가 나눠 쓰므로, 세션 상태가 같은지, 트랜잭션이 닫혔는지, 커넥션이 DB 쪽 수명 안에 있는지가 모두 재사용 조건이 된다. 도입 전에는 Proxy 설정 값보다 애플리케이션 커넥션 풀이 커넥션을 반납할 때 무엇을 실행하는지, 커넥션 수명을 어떻게 정하는지, 접속할 때 무엇을 보내는지를 확인했어야 했다. 타임아웃과 상한은 애플리케이션, Proxy, 데이터베이스 순으로 아래 계층일수록 같거나 길게 맞춘다. 엔드포인트만 바꾸는 한 번의 전환은 실패하면 모든 서비스에 한꺼번에 번지므로 단계적으로 옮겨야 한다.

  2. 증상

    GCP 의 관리형 커넥션 풀러에서 자체 운영 PgBouncer 로 옮기는 첫 운영 카나리에서, 일부 음성 요청이 대화 도중 멈췄다가 정확히 300초 뒤 타임아웃됐다. 다른 요청은 그보다 훨씬 일찍 SQLAlchemy 커넥션 풀 고갈로 실패했다.

    촉발

    Decagon 이 GCP 의 관리형 커넥션 풀러에서 자체 운영 PgBouncer 로 옮기면서 PgBouncer 와 Postgres 사이의 TLS 경로가 바뀌었다. 첫 운영 카나리에서 이 바뀐 경로 때문에, PgBouncer 에 숨어 있던 버그가 드러날 마지막 조건이 갖춰졌다.

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

    운영 카나리 중 일부 음성 요청이 대화 도중 멈추고 정확히 300초 뒤 타임아웃됐다. Sentry 에 "SSL connection has been closed unexpectedly" 오류가 몇 건 찍혔고, 다른 요청은 SQLAlchemy 커넥션 풀 고갈로 실패했다.

    조치
    • 애플리케이션에서 application name 값을 줄여 ParameterStatus 패킷이 PgBouncer 의 작은 패킷 파싱 기준 아래에 머물게 했고, 버그의 세 조건 중 하나를 없애 마이그레이션을 계속했다.
    후속 조치
    • PgBouncer 업스트림에 이벤트 루프 버그의 수정을 머지했다. epoll() 대기로 돌아가기 전에 SSL_pending() 을 확인하고, OpenSSL 에 복호화된 바이트가 남아 있으면 계속 읽는다.
    교훈

    인프라 마이그레이션은 자기 시스템만 바꾸는 것이 아니라 스택의 다른 곳에 숨어 있던 버그를 드러낼 수 있다. 이번에는 자체 운영 PgBouncer 로 옮긴 일이 SQLAlchemy, PgBouncer, OpenSSL, PostgreSQL wire protocol 이 얽힌 오래된 예외 상황이 드러날 마지막 조건을 만들었다. 버그는 응답이 정확히 그 모양일 때는 늘 재현됐지만, 그런 응답 자체가 드물어 스테이징에서 나타나지 않았다.

  3. 증상

    2026년 3월 25일 12:13 PDT부터 15:30 PDT까지 Discord 의 음성·영상 기능이 크게 망가졌다. 사용자 대부분이 통화를 시작하거나 참여하지 못했고, 통화 상태에는 “Awaiting Endpoint” 메시지가 떴다.

    촉발

    Elixir 서비스를 쿠버네티스로 옮기던 중, 주말 CPU 사용률을 낮추려고 sessions 서비스 파드의 CPU 와 메모리를 늘리고 파드 수를 그만큼 줄이는 변경을 배포했다. 레플리카 수가 줄자 쿠버네티스가 첫 번째 존의 파드 50% 를 종료했고, 진행 중인 다른 작업을 기다리는 안전 검사 때문에 핸드오프가 시작되기 전에 종료 유예 시간이 끝났다.

    원인
    구성 요소
    기여 요인
    조치
    • 13:43 PDT까지 calls, streams, guilds 서비스에 낮은 syncer 생성 제한을 넣고 voice syncers 클러스터를 다시 재시작했다. 막히는 supervisor 가 gun supervisor 로 바뀌면서 인스턴스들이 etcd 등록을 유지했고 일부 syncer 의 RPC 를 SFU 로 보냈다.
    • 인스턴스를 골라 하나씩 다시 재시작했고, 14:03에 재시작한 인스턴스 2-3 처럼 일부 인스턴스가 완전히 회복했다.
    • 인스턴스 15대를 추가로 올려 voice syncers 클러스터의 용량을 두 배로 늘렸다. 새 인스턴스들은 메일박스 대기열 문제 없이 syncer 를 받았고, 인스턴스당 syncer 수가 절반이 됐다.
    • 14:26에 마지막으로 막혀 있던 인스턴스를 재시작해 두 배로 늘어난 클러스터가 완전히 정상이 됐다.
    후속 조치
    • Elixir 워크로드용 validating admission webhook 을 쿠버네티스 클러스터에 넣어, 파드가 프로세스를 다 넘기기 전에는 워크로드를 줄이는 업데이트를 거부한다.
    • 부하 테스트 뒤 Holster.Pool 의 supervisor 를 PartitionSupervisor 로 바꿔, 연결 풀 요청을 독립된 여러 supervisor 에 나누고 나가는 연결을 동시에 만들거나 꺼낼 수 있게 했다.
    • gun 연결 프로세스의 생명주기 관리를 그 프로세스를 만드는 Holster.Pool 로 옮겨 gun 연결 supervisor 를 아예 쓰지 않게 했다.
    • voice syncers 를 호출하는 상위 서비스의 속도 제한을 다시 조정해 더 정확히 걸리게 했다. 필요하면 로드 셰딩 도구로 이 제한을 강제로 적용해 voice syncer 를 다시 만들게 할 수도 있다.
    • voice syncers 의 엔드포인트 선택에 새 속도 제한을 넣고 조정해, 나가는 연결 생성을 제한하는 수단을 하나 더 뒀다.
    • HTTP 연결 풀링 메일박스에 감시를 더해 언제 문제가 되고 언제 아닌지 더 분명히 알 수 있게 했다.
    • 서비스 디스커버리 등록과 voice syncer 에서 SFU 로 가는 RPC 트래픽의 계측과 로그를 전부 검토하고 넓혔다.
    • 메일박스 상태 합계 같은 간접 지표 대신, 모든 서비스에서 가장 중요한 프로세스를 직접 감시하도록 넓혀 간다.
    • 더 많은 워크로드를 쿠버네티스로 옮겨, VM 을 손으로 준비하는 대신 명령 하나로 파드를 늘릴 수 있게 한다.
    • A/V 인프라의 컨트롤 플레인 서비스를 여러 리전에 수평 확장해 신뢰성과 리전 장애 내성을 얻고, 나가는 연결 급증을 전 세계에 고르게 흩는다.
    교훈

    충분히 큰 트래픽 급증은 시스템 어딘가의 병목을 찾아낸다. 이전의 큰 부하 장애에서는 여러 ScyllaDB 데이터베이스가 복구를 막았지만, 이번에는 데이터베이스가 잘 버텼고 병목이 음성 서비스로 옮겨 갔다. 용량 한계를 만나면 공급을 늘리거나 수요를 줄이는 두 길이 있고, Discord 는 장애 대응과 사후 조치를 정할 때 이 질문을 분명히 던진다. 장애 중에는 쓸 수 있는 도구를 알아야 한다. Elixir 와 BEAM 가상 머신에서는 어떤 프로세스의 상태든 꺼내 볼 수 있고 핫패치로 관측을 더할 수도 있다. 분산 시스템에서는 장애 모드를 따져야 한다. Elixir 프로세스는 메시지를 하나씩 처리하므로 바쁜 프로세스의 핵심 루프가 느려지면 서비스와 사용자 경험이 함께 나빠진다. Discord 는 사후 검토에서 장애를 어떻게 피할지뿐 아니라 일어난 뒤 어떻게 더 빨리 풀지도 물었고, 복구 시간을 줄이면 관계없는 장애에서도 더 빨리 회복할 수 있다고 봤다.

  4. 증상

    2026년 1월 9일 19:40 UTC 에 US 리전의 Inbox Heartbeat Anomaly 알람이 울려 장애가 선언되었다. US 리전에 호스팅된 고객은 Intercom 서비스를 전혀 쓸 수 없었다.

    촉발

    테스트용으로 테이블을 옮기는 MoveTables 명령이 제공업체 Kubernetes 클러스터의 일시적인 네트워크 문제로 실패했다. 이 실패를 처리하는 과정에서 Vitess v22 의 롤백 로직 버그 때문에 운영 데이터베이스에 빈 VSchema 가 적용되었다.

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

    19:40 UTC 에 US 리전의 Inbox Heartbeat Anomaly 알람이 울려 장애가 선언되었다. 19:41 UTC 에 엔지니어들과 인시던트 커맨더가 장애를 확인하고 조사를 시작했다.

    조치
    • PlanetScale 엔지니어가 장애 한 시간 전에 찍어 둔 VSchema 스냅샷을 다시 적용해 라우팅 토폴로지를 되살렸다.
    • PlanetScale 엔지니어가 실패한 MoveTables workflow 가 남긴 잔여물을 지웠다.
    • 21:00 UTC 이후 Vitess 를 v21 로 롤백하기 시작했고, 그 뒤 몇 시간에 걸쳐 끝냈다.
    후속 조치
    • PlanetScale 이 회귀를 일으킨 코드 경로를 찾았고 수정을 배포한다.
    • Vitess 수정 패치가 충분히 검증될 때까지 Intercom 인프라의 추가 데이터베이스 업그레이드를 멈춘다.
    • PlanetScale 이 장애 시작 때 Kubernetes 네트워크에서 패킷이 드롭된 원인을 찾는다.
    • 잘못된 토폴로지 갱신이 애플리케이션에 닿지 않게 막을 안전장치를 PlanetScale 과 함께 더 찾는다.
    • 데이터베이스 'branch unfreeze' 가 대기 중이던 버전 업그레이드를 자동으로 시작하게 만든 파이프라인 설정을 PlanetScale 과 함께 검토한다.
    • 의도하지 않은 배포가 일어나지 않도록 유지보수 작업과 버전 업그레이드를 더 엄격하게 나눈다.
  5. 증상

    Railway 백엔드 API 가 트래픽을 받지 못해 대시보드 접속, CLI 작업, GitHub 기반 배포 처리, 로그인, API 가 멈췄다. 이미 돌고 있던 배포는 계속 온라인이었고, 이 시스템들을 쓰지 않은 사용자는 영향을 받지 않았다.

    촉발

    엔지니어들이 15:03 UTC 에 데이터 마이그레이션이 들어간 데이터베이스 스키마 변경을 머지했다. 이 마이그레이션은 약 10억 행이 있고 많이 쓰는 테이블에 nullable 열을 더하는 것이었다.

    원인
    구성 요소
    기여 요인
    후속 조치
    • 데이터베이스 연결 수를 늘리고, PgBouncer 가 그 한도 안에서 동작하도록 다시 설정한다.
    • 오래 도는 쿼리를 고쳐 행 잠금 문제가 다시 나지 않게 한다.
내 클러스터에도 있는지 확인하기

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

원인별6

설정 변경2건

  1. IL-0574 운영 환경의 DB 접속 경로를 Amazon RDS Proxy로 바꾼 지 몇 분 만에 Aurora MySQL writer CPU가 100%에 이르고 에러가 났다
    Safie2026
  2. IL-0499 세션 서버가 대량으로 내려간 뒤 음성 통화 라우팅 서비스가 과부하로 멈춰 음성·영상 통화가 세 시간 넘게 연결되지 않았다

소프트웨어 결함1건

조직
  1. IL-0313 자체 운영 PgBouncer 로 옮기는 운영 카나리에서 일부 요청이 정확히 300초 멈추고 SQLAlchemy 커넥션 풀이 고갈됐다

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

  1. IL-0304 Intercom US 리전에서 Vitess 의 라우팅 설정 VSchema 가 빈 값으로 덮여 서비스 전체가 71분 동안 멈췄다
  2. IL-0316 밀린 배포가 한꺼번에 몰린 Control Plane 에서 새 버전 PgBouncer 가 CPU 와 메모리를 비정상적으로 많이 써 데이터베이스 연결이 타임아웃됐다
  3. IL-0498 Postgres 데이터베이스 부하가 15분마다 치솟아 나흘 동안 요청 실패와 지연 급증이 간헐적으로 이어졌다
    Clerk2025
  4. IL-0308 RevenueCat 이 Aurora PostgreSQL 10 에서 14 새 클러스터로 넘어간 직후 쿼리가 극도로 느려져 대시보드와 SDK 엔드포인트가 세 시간 넘게 실패했다

배포 결함3건

  1. IL-0369 데이터베이스 마이그레이션이 잠금에 막히는 동안 Railway 백엔드 복제본이 헬스 체크에 실패해 대시보드와 API 가 멈췄다
  2. IL-0315 약 10억 행 테이블에 인덱스를 만드는 스키마 변경이 테이블 전체를 잠가 Railway 의 백엔드 API 가 멈췄다
  3. IL-0307 Supabase us-east-1 에서 Supavisor 2.0 업그레이드 뒤 Postgres 연결 풀러가 테넌트 약 80% 의 연결을 끊었다

클라우드 제공자 장애1건

기여 요인
–
  1. IL-0368 AWS us-east-1 장애 동안 PlanetScale 컨트롤 플레인이 멈추고, 이어 일부 데이터베이스 브랜치가 네트워크 분할로 쿼리에 실패했다

용량 한계2건

  1. IL-0312 max_connections 를 올리려고 재시작한 주 PostgreSQL 데이터베이스가 다시 올라오지 않아 Gadget 의 모든 앱 요청이 멈췄다
    Gadget2024
  2. IL-0302 GitHub 의 공용 MySQL 클러스터 mysql1 이 최대 부하 시간대에 연결이 바닥나 쓰기 작업이 네 번 멈췄다
    GitHub2022