IL-0316 Railway · 2025-09-22database
밀린 배포가 한꺼번에 몰린 Control Plane 에서 새 버전 PgBouncer 가 CPU 와 메모리를 비정상적으로 많이 써 데이터베이스 연결이 타임아웃됐다
Railway 대시보드와 프로젝트 캔버스는 API 에서 데이터를 받는다. 팀은 코드 정리 중 쓰지 않는 컬럼을 지우는 스키마 변경을 했고, 뒤이은 코드 변경이 그 일부를 의도치 않게 되돌려 프런트엔드가 쓰는 핵심 API 가 실패했다. 2025-09-22 11:05 UTC 에 캔버스가 열리지 않는다는 신고가 들어왔고, 11:14 UTC 에 부분 장애로 사고를 선언했으며, 15분 안에 수정을 배포해 11:45 UTC 에 해결로 표시했다.
첫 문제가 풀리자 밀려 있던 배포가 한꺼번에 시작됐고, 이 부하를 Control Plane 이 감당하지 못해 데이터베이스 오류가 늘었다. 11:48 UTC 에 Control Plane 의 자원 사용과 API 지연이 비정상으로 올라 새 사고를 열었고, Free, Trial, Hobby 사용자의 배포를 멈췄다. 12:14 UTC 에 두 문제가 이어진 것을 알고 원래 사고를 다시 열었다. 12:25 UTC 에 Pro 를 포함한 모든 배포를 최대 20분 멈췄다. 12:44 UTC 에 Pro, 12:50 UTC 에 그 밖의 사용자 배포를 되살렸지만, 13:05 UTC 에 Control Plane 이 계속 불안정해 Pro 가 아닌 사용자의 배포를 다시 멈췄다. 그 사이 Control Plane 데이터베이스의 CPU, 메모리, IOPS 를 크게 늘리고 커넥션 한도를 조정했지만 성능 문제는 이어졌다.
조사 끝에 커넥션 풀러인 PgBouncer 가 정상 범위를 넘는 CPU 와 메모리를 쓰는 것을 찾았다. Railway 는 오래된 Bitnami 이미지를 쓰다가 Bitnami 가 공개 이미지를 지원 중단하자 내부 미러 저장소로 옮겼다. 이 과정에서 PgBouncer 가 몇 버전 올라갔다. 새 버전은 부하가 걸리자 CPU 와 메모리를 비정상적으로 많이 써 지연과 데이터베이스 연결 타임아웃을 일으켰다. Railway 는 PgBouncer 의 기본 구성이 호환되지 않게 바뀐 것을 가능성이 높은 원인으로 보았다. 팀은 설정을 맞추는 대신 안정적이던 이전 PgBouncer 버전으로 곧바로 롤백했고, 성능이 100배 좋아지며 모든 지표가 정상으로 돌아왔다. 14:01 UTC 에 모든 사용자 등급의 배포가 돌아온 것을 확인했다. 21:27 UTC 에는 사설 네트워크와 그 엔드포인트가 대시보드에 보이지 않던 드문 경우를 뒤늦게 고쳤다.
- 심각도
- –
- 영향 범위
- Dashboard (project canvas stuck loading) and the deployment pipeline across Dashboard, GitHub webhooks and CLI; deployments suspended for non-Pro users and, for up to 20 minutes, for all users; running deployments and platform-level networking stayed online
- 영향 사용자
- Users who opened the dashboard or started deployments during the incident
- 지역
- –
- 감지까지
- –
- 복구까지
- 2h 56m
증상
2025-09-22 11:05 UTC 에 Railway 프로젝트 캔버스가 열리지 않는다는 첫 신고가 들어왔다. 캔버스는 실제 오류를 보여 주지 않고 끝없이 로딩 상태에 머물렀다.
11:35 UTC 에 첫 문제를 고치고 11:45 UTC 에 해결로 표시했다. 그러나 11:48 UTC 에 Control Plane 의 자원 사용이 비정상으로 늘고 API 지연이 높아졌다. 대시보드, GitHub 웹훅, CLI 어디서든 배포가 실패했고 대시보드 로딩 실패가 이어졌다. 팀은 이것을 새 사고로 열었다가 12:14 UTC 에 두 문제가 이어져 있다는 것을 알고 원래 사고를 다시 열었다.
대시보드는 서비스 도메인과 사설 네트워크 엔드포인트 같은 핵심 데이터를 Control Plane API 에서 받기 때문에 제대로 열리지 않았다. 배포를 시작한 사용자는 "Limited Access" 메시지를 보았고, 일부 사용자는 "Invalid database URL" 문제를 겪거나 사설 네트워킹이 보이지 않았다.
밀린 배포가 한꺼번에 시작되며 Control Plane 이 감당하지 못했고, 이것이 데이터베이스 오류 증가로 나타났다. Control Plane 의 API 서버에서는 CPU 와 메모리가 치솟았고, 지연이 늘며 데이터베이스 연결이 타임아웃됐다.
팀은 처음에 Control Plane 데이터베이스의 용량을 의심해 CPU, 메모리, IOPS 를 늘리고 커넥션 한도를 조정했지만 성능 문제는 그대로였다. 더 조사하자 커넥션 풀링 계층인 PgBouncer 가 정상 범위를 넘는 CPU 와 메모리를 쓰고 있었다.
원인
- 촉발
- 코드 정리 중 쓰지 않는 컬럼을 지우는 스키마 변경을 했는데, 뒤이은 코드 변경이 그 일부를 의도치 않게 되돌려 프런트엔드가 쓰는 핵심 API 가 실패했다. 이 문제를 고친 뒤 밀린 배포가 한꺼번에 시작되면서, 몇 버전 올라간 PgBouncer 를 쓰던 Control Plane 이 부하를 이기지 못했다.
감지
11:05 UTC 에 사용자들이 Railway 프로젝트 캔버스가 열리지 않는다고 신고했다. 두 번째 문제는 11:48 UTC 에 Control Plane 의 자원 사용이 비정상으로 늘고 API 지연이 높아지면서 드러났다.
조치
- 사고를 선언하고 15분 안에 수정을 배포해 프로젝트 캔버스 문제를 풀었다.
- 먼저 Free, Trial, Hobby 등급 사용자의 배포를 멈춰 Pro 사용자는 평소대로 배포하게 하고 배포 대기열이 차츰 줄게 했다.
- 가장 불안정할 때는 Pro 를 포함한 모든 새 배포를 최대 20분 멈춰 대기열을 더 줄였다.
- Control Plane 데이터베이스의 CPU 와 메모리를 늘리고, 커넥션 한도를 조정하고, IOPS 용량을 늘렸다.
- 설정을 손보는 대신 안정적이던 이전 PgBouncer 버전으로 곧바로 롤백했고, 성능이 100배 좋아지며 모든 지표가 정상으로 돌아왔다.
- 롤백 뒤 Pro 가 아닌 사용자 모두의 배포를 다시 열었다.
- 21:27 UTC 에 사설 네트워크와 그 엔드포인트가 대시보드에 보이지 않던 드문 경우를 뒤늦게 고쳤다.
후속 조치
- Control Plane 저장 계층의 큰 부분을 Postgres 밖으로 옮기는 재설계를 계속한다. 이 작업은 3분기 초에 시작했고, 한 리전의 Control Plane 장애가 플랫폼 전체에 번지는 것을 막고 지금의 Postgres 보다 몇 자릿수 높은 IOPS 를 낼 것을 목표로 한다.
- CI 파이프라인 검증을 강화해 중단을 일으키는 스키마 변경이 운영에 닿지 못하게 하고, 백엔드 배포 전에 스키마 호환성을 자동으로 검사한다.
- PgBouncer 노드의 CPU, 메모리, 커넥션 풀 사용률을 모니터링하고 알림을 건다.
- PgBouncer 업그레이드는 한꺼번에 하지 않고 인스턴스마다 단계적으로 적용한다.
교훈
Railway 는 호환되지 않는 스키마 변경이 운영에 닿지 않았다면 이번 연쇄 장애가 없었을 것으로 보았다. PgBouncer 의 성능 저하를 미리 알았다면 훨씬 빨리 복구할 수 있었다고 했다. PgBouncer 를 한꺼번에 올리지 않고 인스턴스마다 차례로 올렸다면 전체에 퍼지기 전에 버전별 성능 문제를 찾았을 것이라고도 했다.
출처
관련 사례
같은 원인 · 공통 데이터베이스 프록시와 커넥션 풀러, 데이터베이스
같은 원인 · 공통 데이터베이스 프록시와 커넥션 풀러, 데이터베이스
IL-0308RevenueCat 이 Aurora PostgreSQL 10 에서 14 새 클러스터로 넘어간 직후 쿼리가 극도로 느려져 대시보드와 SDK 엔드포인트가 세 시간 넘게 실패했다RevenueCat · 2022같은 원인 · 공통 데이터베이스 프록시와 커넥션 풀러, 데이터베이스
IL-0572Merpay 회계 이벤트 처리 시스템에서 Cloud Pub/Sub 메시지 1000만 건이 밀려 새 회계 데이터가 하루 넘게 Cloud Spanner에 들어가지 못했다Mercari · 2026같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
IL-0444Aurora MySQL 에서 ALTER TABLE 을 실행할 때마다 그 테이블을 reader 로 읽던 커넥션이 끊겨 애플리케이션 오류가 쏟아졌다Repro · 2024같은 원인 · 공통 데이터베이스
IL-0117인그레스 업그레이드가 네트워크 컨트롤 플레인 회귀를 일으켜 데이터 플레인이 잠깐 끊겼고, 한꺼번에 재시작한 서비스들이 백엔드 저장소에 과부하를 일으켜 OpenAI API 오류가 늘었다OpenAI · 2024같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
같은 원인 · 공통 데이터베이스
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0316
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0316/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.