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
                        `,
                },

Reply via email to