Skip to content

[-] fix PgBouncer reconnect by pgxpool ping, closes #1570 - #1576

Open
pashagolub wants to merge 1 commit into
masterfrom
fix-pgbouncer-pool-ping
Open

pashagolub wants to merge 1 commit into
masterfrom
fix-pgbouncer-pool-ping

Conversation

@pashagolub

@pashagolub pashagolub commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Description

pgwatch reconnects to PgBouncer on every metric fetch. PgBouncer logs an error each time:

ERROR invalid command '-- ping', use SHOW HELP;
WARNING C-0x...: pgbouncer/pgbouncer@...:36340 pooler error: invalid command '-- ping', use SHOW HELP;
LOG C-0x...: pgbouncer/pgbouncer@...:36340 closing because: client close request (age=5s)
LOG C-0x...: pgbouncer/pgbouncer@...:36354 login attempt: db=pgbouncer user=pgbouncer

Cause

pgxpool.Acquire pings any connection that has been idle for more than a second before handing it out (pgxpool/pool.go), and pgconn.Ping sends -- ping. The PgBouncer admin console rejects that statement, so the pool discards the connection and opens a new one. With pgbouncer_stats: 5 this happens on every fetch.

This is not a regression. pgxpool has pinged on acquire since pgx v5, and source connections have been pools since #521. #639 fixed the same error message for the connect path only, by replacing pgwatch's own Conn.Ping call with SHOW VERSION; the pool-internal ping was never covered, so #625 was closed while half-fixed.

Fix

Set ShouldPing to always return false for PgBouncer sources. Connect() and Ping() still validate the connection with SHOW VERSION, so liveness is checked where it matters; a connection that dies while idle now surfaces as an error on the next metric query instead of at acquire time. Telegraf took the same approach in influxdata/telegraf#19258.

ShouldPing requires pgx v5.7.6 or newer; we are on v5.11.0.

Verification

Reproduced the bug against cybertecpostgresql/pgwatch:6.0.0 and edoburu/pgbouncer:v1.25.2-p0 with the compose file from the issue: a fresh login every 5 seconds, each closing with invalid command '-- ping'.

The fix itself has not yet been run against a live PgBouncer; it is verified by code inspection only. Worth a manual check before merge.

Fixes #1570

AI & Automation Policy

  • I am the human author and take full personal responsibility for every change in this PR.
  • No AI or automated generative tool was used in any part of this PR OR I have disclosed all tool(s) below.

AI/automation tools used (leave blank if none):

Investigated, reproduced and drafted with Claude Code.

Checklist

  • Code compiles and existing tests pass locally.
  • New or updated tests are included where applicable.
  • Documentation is updated where applicable.

go build ./internal/sources/ passes and gofmt is clean, but the full build and test run could not be done locally: protoc is not installed, so api/pb is not generated and internal/testutil fails to compile. Leaving the first box for CI and the author.

 #1570

pgxpool pings any connection idle for more than a second before handing it
out, and pgconn.Ping sends `-- ping`. The PgBouncer admin console rejects
that with "invalid command", so the pool discards the connection and logs
in again on every metric fetch.

Disable the pool's liveness ping for PgBouncer sources. Connect() and
Ping() still validate the connection with SHOW VERSION.
@pashagolub pashagolub changed the title [-] fix PgBouncer reconnect loop caused by pgxpool liveness ping [-] fix PgBouncer reconnect by pgxpool liveness ping, closes #1570 Sep 18, 2026
@pashagolub pashagolub changed the title [-] fix PgBouncer reconnect by pgxpool liveness ping, closes #1570 [-] fix PgBouncer reconnect by pgxpool ping, closes #1570 Sep 18, 2026
@pashagolub pashagolub self-assigned this Sep 18, 2026
@pashagolub
pashagolub requested a review from 0xgouda September 18, 2026 14:43
@pashagolub pashagolub added bug Something isn't working sources What sources and in what way to monitor labels Sep 18, 2026
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 35357768818

Coverage decreased (-0.1%) to 87.777%

Details

  • Coverage decreased (-0.1%) from the base build.
  • Patch coverage: 2 of 2 lines across 1 file are fully covered (100%).
  • 8 coverage regressions across 1 file.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

8 previously-covered lines in 1 file lost coverage.

File Lines Losing Coverage Coverage
internal/sinks/prometheus.go 8 92.19%

Coverage Stats

Coverage Status
Relevant Lines: 6193
Covered Lines: 5436
Line Coverage: 87.78%
Coverage Strength: 1.0 hits per line

馃挍 - Coveralls

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

Labels

bug Something isn't working sources What sources and in what way to monitor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PgBouncer: pgx sends unsupported -- ping and reconnects

2 participants