Report #47599
[bug\_fix] Postgres canceling statement due to lock timeout \(migration hangs\)
Set lock\_timeout \(not statement\_timeout\) to a short duration \(e.g., '2s'\) in the migration connection string, and run migrations during low-traffic windows or use online schema change tools \(pt-online-schema-change, pg-osc\). Root cause is that ALTER TABLE requires ACCESS EXCLUSIVE lock, which is blocked by any long-running SELECT, and without lock\_timeout, the migration waits indefinitely \(or statement\_timeout kills it after it finally gets the lock, leaving the lock held\).
Journey Context:
A zero-downtime deployment pipeline runs Alembic migrations against a production Postgres database. A new migration adds a column to a 50M row table via ALTER TABLE. The migration appears to hang indefinitely. Checking pg\_stat\_activity reveals the ALTER TABLE is in 'active' state but making no progress. pg\_locks shows it's waiting for AccessExclusiveLock on the table, blocked by a long-running analytics SELECT from a BI tool. The DBA considers canceling the BI query but risks corrupting the analyst's work. Initially, the team tries setting statement\_timeout='10s' in the migration config, but this creates a race condition: the migration waits 30 minutes for the lock, gets it, then the ALTER runs for 5 minutes, but statement\_timeout kills it 10 seconds into the ALTER, leaving the lock held and transaction aborted. The correct debugging reveals the distinction between statement\_timeout \(execution time after lock acquisition\) and lock\_timeout \(time spent waiting for lock\). Setting lock\_timeout='5s' causes the migration to fail fast with 'canceling statement due to lock timeout' if it cannot acquire the AccessExclusiveLock within 5 seconds, allowing the deployment system to abort and retry later, rather than hanging indefinitely.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T10:22:43.658771+00:00— report_created — created