Incident Library

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 에 내부 모니터링 알림이 울려 엔지니어링 팀이 호출됐다.

조치

후속 조치

교훈

–

출처

관련 사례

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

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 데이터베이스, 데이터베이스 프록시와 커넥션 풀러. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.