Skip to content

fix: WAL health panel false positive on idle databases#56

Open
christophebeling wants to merge 1 commit into
cloudnative-pg:mainfrom
christophebeling:fix/wal-health-idle-false-positive
Open

fix: WAL health panel false positive on idle databases#56
christophebeling wants to merge 1 commit into
cloudnative-pg:mainfrom
christophebeling:fix/wal-health-idle-false-positive

Conversation

@christophebeling

Copy link
Copy Markdown

Summary

  • Fixes the WAL health stat panel (ID 612) showing "Unsynced" (red) on idle databases where no WAL activity is occurring
  • Adds a ready > 0 guard so the panel only reports degraded status when there are actually WAL files pending archival
  • Updates the panel description to document the idle database behavior

Problem

PostgreSQL's archive_timeout only forces WAL segment switches when there are records in the current segment. On idle databases (common in staging/dev environments), no new WAL segments are produced, causing seconds_since_last_archival to grow indefinitely. The panel's thresholds (>360s = Delayed, >900s = Unsynced) trigger false positives.

Evidence from a staging environment with 3 CNPG clusters:

  • All clusters showed 50,000+ seconds since last archival
  • failed_count = 0, ready WALs = 0, rate(wal_bytes) = 0
  • After a single write transaction, archiving resumed immediately (~20s)

Fix

The query is multiplied by cnpg_collector_pg_wal_archive_status{value="ready"} > bool 0:

  • When ready > 0 (WALs pending): returns the actual archival age → thresholds work as before
  • When ready == 0 (nothing to archive): returns 0 → maps to "Healthy"

Test plan

  • Verify panel shows "Healthy" on an idle database with no pending WAL files
  • Verify panel shows "Delayed"/"Unsynced" when WAL files are genuinely stuck (ready > 0)
  • Verify panel shows correct status during normal operation with active writes

Fixes #55

@christophebeling
christophebeling force-pushed the fix/wal-health-idle-false-positive branch 3 times, most recently from 0d629ba to 64c4b7c Compare March 13, 2026 07:42
The WAL health stat panel (ID 612) shows "Unsynced" (red) on idle
databases where no WAL activity is occurring, even though the archiver
is functioning correctly.

PostgreSQL's archive_timeout only forces WAL segment switches when
there are records in the current segment. On idle databases (common in
staging/dev), no new WAL segments are produced, causing
seconds_since_last_archival to grow indefinitely and the panel to
turn red.

Fix: multiply the archival age by whether there are actually WAL
files pending archival (ready > 0). When no WALs are pending, the
result is 0 (Healthy) since the archiver has nothing to do.

Fixes cloudnative-pg#55

Signed-off-by: Christoph Ebeling <c.ebeling@nexode.de>
@christophebeling
christophebeling force-pushed the fix/wal-health-idle-false-positive branch from 64c4b7c to ec0d993 Compare March 13, 2026 07:44
@klu4ic

klu4ic commented Mar 26, 2026

Copy link
Copy Markdown

I have the same issue

jrmclx added a commit to jrmclx/grafana-dashboards that referenced this pull request May 20, 2026
fix: WAL health panel false positive on idle databases
cloudnative-pg#56
jrmclx added a commit to jrmclx/grafana-dashboards that referenced this pull request May 28, 2026
* Change Prometheus expression to use max function

Objective is to fix "First Recoverability Point" panel (id 237) returning "vector cannot contain metrics with the same labelset" error

The panel query was failing with the error "vector cannot contain metrics with the same labelset" when both metrics matched by __name__=~ share the same labelset, because Prometheus drops the __name__ label during vector evaluation, causing a collision.

The fix wraps the selector with max(), which is already used in the equivalent panel elsewhere in the same dashboard (panel id 364). This deduplicates the series and resolves the collision.

Before:

{__name__=~"cnpg_collector_first_recoverability_point|barman_cloud_cloudnative_pg_io_first_recoverability_point",namespace=~"$namespace",pod=~"$instances"}*1000 > 0


After:

max({__name__=~"cnpg_collector_first_recoverability_point|barman_cloud_cloudnative_pg_io_first_recoverability_point",namespace=~"$namespace",pod=~"$instances"})*1000 > 0


* Changed reconcile errors panel queries, added "cnpg-cloudnative-pg.+" to Operator Status regex that did not match operator pod.

* Added cnpg-cloudnative-pg.+ to Operator related regex queries

* Added fixed query as proposed in PR56
Fix: WAL health panel false positive on idle databases
cloudnative-pg#56
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.

WAL health panel shows 'Unsynced' on idle databases (false positive)

2 participants