Skip to content

models: enable pool_pre_ping by default - #158

Merged
djgalloway merged 1 commit into
mainfrom
wip-pool-pre-ping
Sep 10, 2026
Merged

djgalloway merged 1 commit into
mainfrom
wip-pool-pre-ping

Conversation

@djgalloway

Copy link
Copy Markdown
Contributor

Every morning ~06:00–06:45 UTC, unattended-upgrades on 1.shaman restarts postgresql (via needrestart) when a dependent package is upgraded. The SQLAlchemy pools keep the now-dead connections, so the first /api/search requests after the restart fail with:

psycopg2.OperationalError: SSL connection has been closed unexpectedly

which surfaces as HTTP 500 to clients. Teuthology jobs querying package versions during that window die with "Failed to fetch package version" — this is the genuine-infra slice of https://tracker.ceph.com/issues/59193 (confirmed against 1.shaman's journal: every recorded 500 lines up with a postgresql@16-main restart from apt-daily-upgrade.service, most recently 2026-09-02 06:41 UTC).

pool_pre_ping tests a pooled connection on checkout and transparently replaces it if the database went away, at the cost of one trivial round-trip per checkout. setdefault keeps it overridable from a config file (pool_pre_ping: False).

Every morning ~06:00-06:45 UTC, unattended-upgrades on 1.shaman restarts
postgresql (via needrestart) when a dependent package is upgraded. The
SQLAlchemy pools keep the now-dead connections, so the first /api/search
requests after the restart fail with

    psycopg2.OperationalError: SSL connection has been closed unexpectedly

which surfaces as HTTP 500 to clients. Teuthology jobs querying package
versions during that window die with "Failed to fetch package version"
(https://tracker.ceph.com/issues/59193).

pool_pre_ping tests a pooled connection on checkout and transparently
replaces it if the database went away, at the cost of one trivial
round-trip per checkout. Use setdefault so a config file can still
opt out with pool_pre_ping: False.

Assisted-by: Claude Fable 5
Signed-off-by: David Galloway <[email protected]>
@djgalloway
djgalloway merged commit 9417cb3 into main Sep 10, 2026
4 checks passed
Comment thread shaman/models/__init__.py
def _engine_from_config(configuration):
configuration = dict(configuration)
url = configuration.pop('url')
# Test pooled connections on checkout and transparently replace dead

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "on checkout" mean here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SQLAlchemy keeps a pool of open DB connections. When a request needs one it checks it out (borrows it from the pool), uses it, then returns it. pool_pre_ping=True means: at that borrow moment, before handing the connection to your code, SQLAlchemy fires a trivial SELECT 1 on it. If that fails, the connection is discarded and a fresh one is opened, transparently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants