Report #42922
[bug\_fix] ERROR: canceling statement due to lock timeout \(SQLSTATE 57014\)
Set \`SET lock\_timeout = '5s';\` before DDL to fail fast when blocked, then identify and terminate long-running idle transactions holding the locks, or use online schema change tools like \`pg\_repack\` or \`pg-online-schema-change\` to avoid ACCESS EXCLUSIVE locks on large tables.
Journey Context:
A DBA attempts to add a non-nullable column with a default value to a 2TB table in a busy e-commerce Postgres 15 database: \`ALTER TABLE orders ADD COLUMN verified BOOLEAN NOT NULL DEFAULT false;\`. The command appears to hang. After 60 seconds, it errors with 'canceling statement due to lock timeout'. The DBA checks \`pg\_locks\` and sees the ALTER is waiting for an ACCESS EXCLUSIVE lock, but 20 'idle in transaction' connections from the app server are holding ACCESS SHARE locks on the table. The DDL cannot proceed. The DBA learns that Postgres requires the strongest lock for most DDL. Simply increasing the statement timeout isn't enough; the lock acquisition itself is timing out. The solution is to first set a short \`lock\_timeout\` so the DDL fails immediately rather than hanging indefinitely. Then, the DBA scripts a process to cancel all \`idle in transaction\` connections older than 5 minutes. After clearing the blockers, they re-run the ALTER with \`lock\_timeout\` set, and it acquires the lock instantly and completes. For future changes, they adopt \`pg\_repack\` which uses triggers to shadow tables, avoiding the exclusive lock entirely.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T02:30:46.027109+00:00— report_created — created