{"id":"IL-0329","org":"incident.io","date":"2025-04-09","docs":[],"title":{"en":"A routine migration left PGAudit stuck holding Postgres locks, causing intermittent timeouts and a 2-minute outage","ko":"Postgres 17 업그레이드 뒤 다시 켠 PGAudit 가 마이그레이션 중 락을 쥔 채 멈춰, 서비스 전반이 느려지고 데이터베이스가 2분 동안 내려갔다"},"domain":["database"],"impact":{"scope":"Intermittent slowness and timeouts across the dashboard, mobile app, Slack app and API from 14:16 to 14:27 UTC, including a primary database outage of just under 2 minutes; on-call alerts and escalations kept working","users":"unknown","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":null,"related":[],"sources":[{"url":"https://status.incident.io/incidents/01JRDFKAGE07YYDY0KZR137BX3/write-up","kind":"official-status","archived":"https://web.archive.org/web/20260418224429/https://status.incident.io/incidents/01JRDFKAGE07YYDY0KZR137BX3/write-up"}],"summary":{"en":"The weekend before the incident, incident.io upgraded its database to Postgres 17 and turned off the PGAudit extension during the upgrade. After testing in staging succeeded, PGAudit was turned back on in production and checked to be working. On Wednesday 9 April at 14:16 UTC a routine migration that created an empty table and added an index interacted with PGAudit in an unexpected way: the extension became unresponsive while holding critical locks. The locked resources blocked other database operations, which showed as intermittent slowness across the dashboard, mobile app, Slack app and API. Killing the PGAudit processes failed because they did not respond to timeout signals, and further kill attempts also failed as timeouts rose.\n\nThe team then chose to restart the database to end the stuck process by force, accepting a short hard outage instead of further disruption. The primary database was down for just under 2 minutes, from 14:25 to 14:27 UTC, and no on-call alerts or escalations were dropped during that time. After service was restored, PGAudit was disabled and then removed entirely so that it could not be switched back on by accident. The cause of the interaction between the migration and PGAudit was still under investigation when the write-up was published.","ko":"incident.io 는 2025년 4월 9일 직전 주말에 데이터베이스를 Postgres 17 로 업그레이드했다. 업그레이드하는 동안 PGAudit 를 잠시 껐다. PGAudit 는 데이터베이스 활동과 데이터베이스 구조, 사용자 권한의 변경을 표준 Postgres 로그보다 자세히 남기는 확장이다. 업그레이드가 끝난 뒤 스테이징에서 시험이 통과하자 운영에서도 PGAudit 를 다시 켰고, 정상 동작을 확인했다.\n\n4월 9일 14:16 UTC 에 빈 테이블을 만들고 인덱스를 더하는 평범한 마이그레이션이 PGAudit 와 예상하지 못한 방식으로 얽혔다. PGAudit 는 중요한 데이터베이스 락을 쥔 채 응답하지 않게 됐다. 엔지니어들은 PGAudit 프로세스를 죽이려 했지만 프로세스가 타임아웃 시그널에 반응하지 않았다. 락이 풀리지 않아 다른 데이터베이스 작업이 막혔다. 대시보드, 모바일 앱, Slack 앱, API 가 간헐적으로 느려졌다.\n\n타임아웃이 계속 늘자 팀은 데이터베이스를 재시작하기로 했다. 재시작하면 멈춘 프로세스가 강제로 끝나지만 데이터베이스도 잠깐 완전히 내려간다. 팀은 혼란이 더 이어지는 위험보다 먼저 손을 쓰는 쪽을 골랐다. 주 데이터베이스는 14:25 부터 14:27 UTC 까지 2분이 조금 안 되게 내려갔다. 인프라의 핵심 부분이 이런 상황을 견디도록 설계돼 있어 그동안에도 온콜 알림과 에스컬레이션은 빠지지 않았다. 복구 뒤 팀은 PGAudit 를 껐다가 완전히 지웠다."},"trigger":{"en":"At 14:16 UTC a routine migration that created an empty table and added an index ran on the production database, where PGAudit had been re-enabled after the weekend upgrade to Postgres 17.","ko":"PGAudit 를 다시 켠 운영 데이터베이스에서 빈 테이블을 만들고 인덱스를 더하는 평범한 마이그레이션을 14:16 UTC 에 실행했다."},"severity":"unknown","symptoms":["lock-contention","intermittent-timeouts","high-latency","service-unavailable"],"timeline":{"detected_after":null,"resolved_after":"11m"},"date_kind":"incident","detection":{"en":"incident.io's monitoring alerted the team to the problem shortly after the migration started.","ko":"모니터링이 문제를 빠르게 알렸다."},"components":["database"],"root_cause":"software-bug","remediation":[{"text":{"en":"Restarted the primary database to force the stuck PGAudit process to end, taking just under 2 minutes of downtime","ko":"PGAudit 프로세스를 죽이는 시도가 계속 실패하자 데이터베이스를 재시작해 멈춘 프로세스를 강제로 끝냈다. 이 때문에 주 데이터베이스가 14:25 부터 14:27 UTC 까지 2분이 조금 안 되게 내려갔다."}},{"text":{"en":"Disabled and then fully removed the PGAudit extension after service was restored","ko":"서비스를 되살린 뒤 PGAudit 확장을 잠시 껐다가 완전히 지웠다."}}],"action_items":[{"text":{"en":"Keep PGAudit removed until its safety can be guaranteed","ko":"PGAudit 가 안전하다고 보장할 수 있을 때까지 확장을 지운 상태로 두어, 실수로 다시 켜질 위험을 없앤다."}},{"text":{"en":"Continue investigating the interaction between the migration and PGAudit","ko":"원인 조사를 계속한다."}},{"text":{"en":"Hold an internal debrief of the incident","ko":"내부 회고를 한다."}},{"text":{"en":"Improve processes and monitoring to detect, prevent and respond to similar situations","ko":"비슷한 상황을 더 잘 감지하고 막고 대응하도록 절차와 모니터링을 보강한다."}}],"contributing":[],"recurrence_of":null,"symptoms_text":{"en":"On 9 April 2025 from 14:16 UTC, incident.io's dashboard, mobile app, Slack app and API became intermittently slow and requests timed out. Monitoring alerted the team soon after a routine migration began on the production Postgres database, and the incident ended with the primary database unavailable for just under 2 minutes, from 14:25 to 14:27 UTC.\n\nThe migration created an empty table and added an index. PGAudit, a Postgres extension for detailed logging of database activity and of changes to database structures and user permissions, stopped responding while it held critical database locks, and other database operations queued behind those locks. The first attempt was to kill the stuck PGAudit processes, but they ignored timeout signals, so the locks were never released and the timeouts kept climbing.","ko":"2025년 4월 9일 14:16 UTC 부터 대시보드, 모바일 앱, Slack 앱, API 가 간헐적으로 느려졌고, 모니터링이 곧 문제를 알렸다. 14:25 부터 14:27 UTC 까지 2분 동안은 데이터베이스가 완전히 내려가 제품 전체가 영향을 받았다.\n\n빈 테이블을 만들고 인덱스를 더하는 평범한 마이그레이션이 돌던 중 PGAudit 프로세스가 응답하지 않게 됐다. 이 프로세스는 중요한 데이터베이스 락을 쥐고 놓지 않았다. 락이 걸린 자원 때문에 다른 데이터베이스 작업이 줄줄이 막혔다.\n\n타임아웃은 시간이 갈수록 늘었다. 엔지니어들은 처음에 문제의 PGAudit 프로세스를 죽이려 했지만, 프로세스가 타임아웃 시그널에 반응하지 않아 락이 풀리지 않았다. 몇 번을 더 시도해도 프로세스는 끝나지 않았다.\n\n이 기간에도 온콜 알림과 에스컬레이션은 하나도 빠지지 않고 동작했다."},"updated_at":"2026-11-14T12:33:58.208319Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0329","org_slug":"incident-io"}