IL-0315 Railway · 2025-10-28database
약 10억 행 테이블에 인덱스를 만드는 스키마 변경이 테이블 전체를 잠가 Railway 의 백엔드 API 가 멈췄다
Railway 의 대시보드, CLI, Public API 같은 클라이언트용 인터페이스는 백엔드에 기대고, 백엔드는 Postgres 를 주 데이터 저장소로 쓴다. 2025-10-28 18:23 UTC 에 스키마 변경을 담은 데이터베이스 변경이 들어갔고, 18:34 UTC 에 운영에 반영됐다. 이 변경은 거의 모든 API 작업이 쓰는 약 10억 행 테이블에 새 컬럼과 인덱스를 더했다. 인덱스를 CONCURRENTLY 옵션 없이 만들었기 때문에 테이블 전체에 배타적 잠금이 걸렸다. 잠금이 걸린 동안 데이터베이스로 가는 모든 쿼리가 인덱스 작업 뒤에 줄을 섰고, API 서버는 요청을 계속 받아 연결을 열 때마다 곧바로 막혔다. PgBouncer 설정이 Postgres 의 커넥션 한도를 넘는 연결을 허용해, 관리용 슬롯까지 모두 찼다.
18:36 UTC 에 내부 모니터링 알림이 울렸고 18:41 UTC 에 사고를 선언했다. 엔지니어는 인덱스 생성을 끝내려 했지만 FATAL: remaining connection slots are reserved for roles with privileges of the "pg_use_reserved_connections" role 오류로 관리용 연결을 맺지 못했다. 18:56 UTC 에 근본 원인을 찾았다. 다른 복구 방법을 찾는 동안 마이그레이션이 약 30분 만에 스스로 끝나 테이블 잠금이 풀렸고, 밀린 작업이 처리되며 커넥션 풀이 정상으로 돌아왔다. 19:00 UTC 에 서비스가 차츰 돌아오는 것을 확인했고 19:15 UTC 에 완전 복구를 확인했다.
- 심각도
- –
- 영향 범위
- Dashboard inaccessible, CLI operations that use the API failed, GitHub-based deployments delayed and all Public API operations disrupted; running deployments and platform-level features stayed online
- 영향 사용자
- Users who opened the dashboard, used the CLI or started a GitHub-based deploy during the incident
- 지역
- –
- 감지까지
- 2m
- 복구까지
- 41m
증상
2025-10-28 18:36 UTC 에 내부 모니터링 알림이 울려 엔지니어링 팀이 호출됐다. 대시보드가 열리지 않았고, railway up 처럼 API 를 쓰는 CLI 작업이 실패했으며, Public API 작업이 모두 멈췄다.
웹훅 처리가 실패해 GitHub 기반 배포가 늦어졌다. 이미 돌고 있던 배포와 플랫폼 수준의 기능은 내내 정상으로 동작했다.
잠긴 테이블 뒤로 모든 쿼리가 줄을 서는 동안 API 서버는 요청을 계속 받았고, 요청마다 연 데이터베이스 연결이 곧바로 막혔다. PgBouncer 설정이 Postgres 의 커넥션 한도를 넘는 연결을 허용해, 관리용 슬롯까지 모든 연결 슬롯이 찼다.
엔지니어가 인덱스 생성을 멈추려고 접속하자 다음 오류가 났다. FATAL: remaining connection slots are reserved for roles with privileges of the "pg_use_reserved_connections" role 관리용 연결을 맺을 수 없어 문제가 된 인덱스 생성을 끝내는 명령을 실행하지 못했다.
원인
원인 배포 결함
- 촉발
- 일상적인 Postgres 데이터베이스 변경으로 약 10억 행 테이블에 새 컬럼과 인덱스가 더해졌다. 인덱스 생성에 CONCURRENTLY 옵션을 쓰지 않아 테이블 전체에 배타적 잠금이 걸렸다.
감지
변경이 운영에 반영되고 2분 뒤인 18:36 UTC 에 내부 모니터링 알림이 울려 엔지니어링 팀이 호출됐다.
조치
- 인덱스를 만드는 마이그레이션이 약 30분 만에 끝나 테이블 잠금이 스스로 풀렸고, 줄을 선 작업이 처리되며 커넥션 풀이 정상으로 돌아왔다.
후속 조치
- CI 에서 모든 인덱스 생성에 CONCURRENTLY 사용을 강제하고, 지키지 않은 풀 리퀘스트는 머지 전에 막는다.
- PgBouncer 커넥션 풀 한도를 조정해 뒤에 있는 Postgres 인스턴스의 용량을 넘지 않게 한다.
- 데이터베이스 사용자별 커넥션 한도를 설정해 장애 중에도 관리용 접속을 보장하고, 어떤 상황에서도 유지 보수 작업을 할 수 있게 한다.
교훈
–
출처
관련 사례
같은 원인 · 공통 데이터베이스, 데이터베이스 프록시와 커넥션 풀러
IL-0307Supabase us-east-1 에서 Supavisor 2.0 업그레이드 뒤 Postgres 연결 풀러가 테넌트 약 80% 의 연결을 끊었다Supabase · 2025같은 원인 · 공통 데이터베이스, 데이터베이스 프록시와 커넥션 풀러
같은 원인 · 공통 데이터베이스
IL-0136Sweden Central 리전에서 내부 서비스 배포가 캐시를 비워 메타데이터 백엔드에 평소 20배의 트래픽이 몰렸고, 데이터베이스 연결에 기대는 헬스 체크가 인스턴스를 계속 재시작시켜 Azure OpenAI 요청이 6시간 가까이 실패했다Microsoft Azure · 2026같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0510MIT Learn 운영 RDS PostgreSQL 의 저장 공간이 임시 파일로 가득 차 learn.mit.edu 가 세 시간 동안 503 과 504 를 냈다MIT Open Learning · 2026같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0547Buildkite 의 Agent API, REST API, GraphQL 이 annotations 테이블 쿼리 타임아웃으로 4시간 가까이 저하됐다Buildkite · 2025같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0324External Storage 데이터베이스 클러스터에 과부하가 걸려 mw-api-int, mw-parsoid, mw-jobrunner 의 지연과 데이터베이스 오류가 늘었다Wikimedia Foundation · 2025같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0523TANF-app 의 운영 배포가 PostgreSQL 마이그레이션 실패로 두 달 동안 막힘U.S. Department of Health and Human Services · 2023같은 원인 · 공통 데이터베이스
IL-0567쿠키런: 오븐브레이크의 패키지 매출 랭킹 기능을 배포한 뒤 Aurora MySQL CPU가 100%에 이르러 유저가 게임에 접속하지 못했다Devsisters · 2023같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0524인덱스를 다시 만드는 마이그레이션이 운영에서 Transactions 테이블을 잠가 Open Collective 서비스가 느려짐Open Collective · 2023같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0315
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0315/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.