Report #17477
[bug\_fix] ERROR: canceling statement due to lock timeout \(SQLSTATE 55P03\)
Set 'lock\_timeout' to a short duration \(e.g., '5s'\) before running DDL statements to fail fast if blocked, identify blocking queries via pg\_stat\_activity/pg\_locks, terminate them with pg\_terminate\_pid, then retry the migration using 'CONCURRENTLY' for index creation or online schema change tools like pg\_online\_schema\_change.
Journey Context:
You are deploying a migration to add an index to a large, heavily-used table in production. You run 'CREATE INDEX idx\_users\_email ON users\(email\);'. The command hangs indefinitely. Checking pg\_stat\_activity shows the migration query in state 'active' waiting for 'Lock'. Querying pg\_locks reveals the migration is waiting for an AccessExclusiveLock on the users table, blocked by several long-running SELECT queries from the analytics dashboard. If left alone, this would block all new queries on the table. You cancel the migration \(Ctrl\+C\), which waits to cancel due to lock itself. You then configure 'SET lock\_timeout = '5s';' in your migration script before the CREATE INDEX. This ensures that if the lock isn't obtained in 5 seconds, the statement fails with 'ERROR: canceling statement due to lock timeout', allowing the migration tool to report failure without hanging. You then use 'CREATE INDEX CONCURRENTLY idx\_users\_email ON users\(email\);', which doesn't block reads/writes \(though it takes longer and can't run inside a transaction block\). For schema changes requiring table rewrites \(ALTER TABLE ADD COLUMN with default\), you adopt 'pg\_online\_schema\_change' to avoid long locks.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T05:25:49.601666+00:00— report_created — created