Switch the PostgreSQL driver from pgx to pgGo - #114
Conversation
pgbot now talks to PostgreSQL through github.com/pgrundev/pggo, a dependency-free wire-protocol client. The connection layer (pool, session pins, read-only transactions, SSH DialFunc, pooler/PgDog probes), the collectors, erd, logs, advise and the MCP tools are ported; pgx, pgpassfile, pgservicefile and puddle leave the module graph. Output is unchanged apart from pgbot's own footprint in sampled counters (see CHANGELOG), verified side by side against PostgreSQL 16-19, a streaming standby, PgBouncer and PgDog. The unit and integration suites pass on 16-19 over TLS+SCRAM, including the pooler tests. go.mod temporarily replaces pggo with ../../pggo until pggo's library release is tagged. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Drops the local replace directive. The integration matrix gains 19beta1, where the pgGo migration was verified. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Since PostgreSQL 15 a backend flushes its counters to pg_stat_database only when it goes idle, so the commits inside one long DO block stay invisible until the block ends. On 15+ the 'non-zero TPS under load' guard therefore only ever saw pgbot's own traffic: the pgx build passed by counting itself (and would have passed with the stats-caching bug it exists to catch); the pgGo build, which generates less self-traffic in the sample window, correctly saw 0 TPS. pgbench runs the same INSERTs as client transactions, which are counted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The first CI run failed On 15+ the guard had therefore only ever seen pgbot's own traffic. Under the same DO-block load, the pgx build passes by counting itself, and would also have passed with the stats-caching bug the guard exists to catch. The pgGo build, which leaves less self-traffic in the window, correctly saw 0 TPS. Fix (86cb1fa, CI only): the load is now pgbench running the same INSERTs as client transactions. The assertion is unchanged. Both the pgx and the pgGo builds pass it locally, and all 21 checks pass here. |
pgrundev#113 landed after pgrundev#114 removed pgx from go.mod, so the test's pgx import left the collect package unbuildable under go vet / go test ./...
Summary
PgBot now talks to PostgreSQL through pgGo v0.1.0, a dependency-free wire-protocol client (standard library only), instead of pgx. pgx, pgpassfile, pgservicefile and puddle leave the module graph.
Ported:
DialFunc, the pooler/PgDog probes, and the Aurora--all-instanceshost override.EXPLAIN (GENERIC_PLAN)via the simple protocol), and the MCP tools.The full audit of what PgBot uses, and how pgGo covers it, is in pggo/docs/pgbot-compatibility.md.
Verification
-race) pass.inspect(JSON and text),activity,queries,indexes,tables,vacuum,waits,erd,lint,tune,logs,advise, and the MCP toolsschema_of/explain_plan/vacuum_health. Every command exceptinspectproduced identical output on every target.inspectdiffers only in PgBot's own footprint on an otherwise idle database. pgGo pipelinesBEGINwith each collector's first query, so PgBot's own commits are mostly not yet flushed topg_stat_databasewhen the sample window closes. Against a rate-limited 200 TPS pgbench workload, pgx-PgBot reported about 220 TPS and pgGo-PgBot about 200. Cache hit and rollbacks were identical. This is documented in the CHANGELOG.Notes
Exec(a pgx simple-protocol behavior) now useSimpleQueryexplicitly. No assertion was weakened.host=a,b) worked implicitly under pgx and are not supported by pgGo. They are not a documented PgBot feature; such a DSN now fails loudly instead of silently picking a member.TestIntegration_selfExclusion_wiringfails identically on pgx and pgGo when other sessions are active (for example, pgbench load or PgBouncer's pooled server connections). It assumes a quiet database, so it is not a migration regression.19beta1.🤖 Generated with Claude Code