Package: prometheus-postgres-exporter
Version: 0.11.1-3+b5
Severity: normal
Tags: patch
Hi,
if prometheus-postgres-exporter runs on a standby, and that standby has
physical replication slots, then the pg_replication_slots metrics queries
throws an error (see also upstream issues #547 [0] and #962 [1]):
|Mai 17 12:20:21 pg2 prometheus-postgres-exporter[8458]:
|ts=2024-05-17T10:20:21.162Z caller=namespace.go:236 level=info err="Error
|running query on database \"/var/run/postgresql/:5432\": pg_replication_slots
|pq: recovery is in progress"
This can be manually reproduced like this:
|postgres=# SELECT pg_create_physical_replication_slot('test');
| pg_create_physical_replication_slot
|-------------------------------------
| (test,)
|(1 row)
|
|postgres=# SELECT pg_is_in_recovery();
| pg_is_in_recovery
|-------------------
| t
|(1 row)
|
|postgres=# SELECT slot_name, database, active,
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)
| FROM pg_replication_slots;
|ERROR: recovery is in progress
|HINT: WAL control functions cannot be executed during recovery.
Usually those functions like pg_current_wal_lsn() are guarded by CASE
pg_is_in_recovery(), but not here (maybe because it is not very common
to have replication slots on standbys). The attached patch should fix
it.
Michael
[0] https://github.com/prometheus-community/postgres_exporter/issues/547
[1] https://github.com/prometheus-community/postgres_exporter/issues/962
Index: prometheus-postgres-exporter-0.11.1/cmd/postgres_exporter/queries.go
===================================================================
--- prometheus-postgres-exporter-0.11.1.orig/cmd/postgres_exporter/queries.go
+++ prometheus-postgres-exporter-0.11.1/cmd/postgres_exporter/queries.go
@@ -105,14 +105,14 @@ var queryOverrides = map[string][]Overri
{
semver.MustParseRange(">=9.4.0 <10.0.0"),
`
- SELECT slot_name, database, active,
pg_xlog_location_diff(pg_current_xlog_location(), restart_lsn)
+ SELECT slot_name, database, active, (case
pg_is_in_recovery() when 't' then null else
pg_xlog_location_diff(pg_current_xlog_location(), restart_lsn) end)
FROM pg_replication_slots
`,
},
{
semver.MustParseRange(">=10.0.0"),
`
- SELECT slot_name, database, active,
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)
+ SELECT slot_name, database, active, (case
pg_is_in_recovery() when 't' then null else
pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) end)
FROM pg_replication_slots
`,
},