SIGN IN SIGN UP

fix(db): reset the migration client's session before it re-enters the pool (#12)

ensureSchema borrows a client from the shared 20-slot pool and, on purpose,
turns OFF that session's statement_timeout and
idle_in_transaction_session_timeout and sets lock_timeout = '5s'. All three are
SESSION-scoped, and the client is then released back into the pool without a
reset.

That leak is permanent for the connection's lifetime:

  - pg-pool's release() does not reset session state (pg-pool/index.js
    _release just re-attaches the idle listener and requeues the client).
  - node-postgres sends the pool's statement_timeout / lock_timeout /
    idle_in_transaction_session_timeout in the connection's STARTUP PACKET
    (pg/lib/client.js), so they are applied once at connect and never
    re-applied on checkout.

So after every boot, one of the 20 pooled connections serves ordinary API
traffic with the pool's runaway-query guards inverted:

  - statement_timeout is 0 instead of 60s. That is the guard db/pool.ts
    documents as the reason a single un-indexed hot query once held all 20
    slots and 503-ed the API; on this connection a runaway pins its slot
    indefinitely again.
  - idle_in_transaction_session_timeout is 0, so a leaked transaction holds
    the slot open forever.
  - lock_timeout is 5s for ordinary writes, which abort with 55P03
    lock_not_available instead of waiting — sporadic 500s that land on
    roughly 1 in 20 requests and are near-impossible to reproduce.

Reset the session in the same breath as handing the slot back, which is the
reasoning already applied to the advisory lock a few lines above ("lets the
conn re-enter the pool with no lock state — cleaner"). A failed RESET still
releases: losing a pool slot forever would be worse than a stale session, and
the pool discards a broken connection on its own.
X
Xialie Zhuang committed
05b0ffca40dee19e7bf3fd145eb9010cbd6e0151
Parent: 01e954d
Committed by GitHub <noreply@github.com> on 8/19/2026, 5:26:18 AM