Report #69005
[bug\_fix] ERROR: canceling statement due to lock timeout \(SQLSTATE 55P03\)
Set a short lock\_timeout \(e.g., '2s'\) in the migration session so DDL statements fail fast if they cannot acquire an AccessExclusiveLock immediately, rather than hanging indefinitely and blocking all other queries on the table. Combine this with application-level retry logic or schedule migrations during maintenance windows. Alternatively, identify blocking PIDs via pg\_locks and pg\_stat\_activity and terminate them safely. Root cause: DDL operations require exclusive table locks; if long-running queries or uncommitted transactions hold weaker locks, the DDL waits, creating a convoy where all new queries queue behind the waiting DDL.
Journey Context:
A Django deployment applies a migration adding an index to a 100GB production table. The command hangs for 30 minutes. Application health checks start failing because all queries on that table are blocked behind the migration's AccessExclusiveLock request, which is waiting for a long-running analytics query to finish. The developer initially thinks Postgres is frozen. Checking pg\_stat\_activity reveals the migration state as 'active' but the query column shows the ALTER TABLE. Querying pg\_locks shows the migration waiting for a lock held by PID 1234. The developer terminates PID 1234, and the migration completes instantly. To prevent recurrence, they configure the migration runner to execute SET lock\_timeout = '2s' before migrations, causing them to fail fast with ERROR: canceling statement due to lock timeout if blocked, allowing the deployment system to retry during the maintenance window.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T22:18:26.309901+00:00— report_created — created