Report #88584
[bug\_fix] Postgres migration hangs waiting for advisory lock via PgBouncer \(transaction mode\)
Bypass PgBouncer for migrations, connecting directly to Postgres; or configure a separate PgBouncer pool in session mode for migration tasks.
Journey Context:
A DevOps engineer migrates a Rails app to use PgBouncer in transaction pooling mode to handle connection spikes. Migrations \(ActiveRecord \`db:migrate\`\) that previously took seconds now hang indefinitely. Logs show 'ActiveRecord::LockWaitTimeout' or the process just stalls. Querying \`pg\_stat\_activity\` on Postgres shows the migration connection stuck in 'idle in transaction' holding an advisory lock, but the next statement from the same client \(multiplexed via PgBouncer\) lands on a different backend process that doesn't have the lock, causing it to wait forever. The engineer realizes PgBouncer's transaction mode is incompatible with session-scoped features like \`pg\_advisory\_lock\`. They modify the CI pipeline to export \`DATABASE\_URL\` pointing directly to the Postgres instance \(bypassing PgBouncer\) for the migration job only. The migration completes successfully because the advisory lock is held on a consistent backend session. Why it works: Advisory locks are tied to the backend process ID; PgBouncer in transaction mode assigns different backends to subsequent queries from the same client, breaking the lock continuity.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T07:16:23.933712+00:00— report_created — created