Skip to content

fix(pgxpool): treat MaxConnLifetime 0 as unlimited in expiry check#2574

Open
AurelienPillevesse wants to merge 1 commit into
jackc:masterfrom
AurelienPillevesse:pgxpool-maxconnlifetime-zero-unlimited
Open

fix(pgxpool): treat MaxConnLifetime 0 as unlimited in expiry check#2574
AurelienPillevesse wants to merge 1 commit into
jackc:masterfrom
AurelienPillevesse:pgxpool-maxconnlifetime-zero-unlimited

Conversation

@AurelienPillevesse

Copy link
Copy Markdown

Problem

When MaxConnLifetime == 0 (whose documented and conventional meaning is "unlimited lifetime", consistent with database/sql.SetConnMaxLifetime(0)), Pool.Acquire always fails with:

too many failed attempts acquiring connection

Instead of returning a connection, it repeatedly creates and destroys connections until the retry limit is reached.

Root Cause

Commit 20578f57 ("feat: check if conn is expired before acquire") introduced an isExpired check in Acquire.

At connection creation time, maxAgeTime is computed as:

maxAgeTime = time.Now().Add(MaxConnLifetime).Add(jitter)

When MaxConnLifetime == 0, maxAgeTime is effectively the connection creation timestamp. As a result, the expiration check:

time.Now().After(maxAgeTime)

becomes true almost immediately.

Consequently, every newly created connection is considered expired as soon as it is acquired. Acquire destroys the connection, creates a new one, and repeats this process up to maxConns + 1 times before eventually returning:

too many failed attempts acquiring connection

The same isExpired logic is also used by the background health checker (checkConnsHealth), causing idle connections to be destroyed immediately as well. This behavior contradicts the expected semantics of MaxConnLifetime == 0, which should represent an unlimited lifetime.

Fix

Treat non-positive values of MaxConnLifetime as meaning "unlimited" by guarding the isExpired function, which is the single source of truth used by both Acquire and checkConnsHealth.

With this change, connections are never considered expired due to age when MaxConnLifetime <= 0, restoring the behavior that existed before the regression and ensuring that MaxConnLifetime == 0 consistently means unlimited lifetime.

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.

1 participant