Zurück zur Startseite

Health Score für PostgreSQL: Gesundheitsüberwachung

Health Score für PostgreSQL aggregiert Metriken zu einem einzigen Score von 0 bis 100 nach Kategorien Verbindungen, Leistung, Speicher. Erkennt gefährliche Kombinationen und erzeugt Empfehlungen. Geeignet für Grafana und Prometheus.

Ein einziger Health Score für PostgreSQL: von 150 Metriken zu einer Zahl
Advertisement 728x90

Gesundheits-Score für PostgreSQL: Ein integrierter Gesundheitsindikator für Ihre Datenbank

Traditionelle Überwachung mit Dutzenden von Grafana-Dashboards führt oft zu Dashboard-Erschöpfung – Betreiber ignorieren Diagramme, Warnungen sind entweder übermäßig mit Fehlalarmen oder kommen zu spät. Der Gesundheits-Score löst dieses Problem, indem er 150+ Metriken aus pg_stat_* zu einer einzigen Bewertung von 0 bis 100 zusammenfasst. Die Formel berücksichtigt Kategoriewichte und gefährliche Kombinationen, sodass eine schnelle Einschätzung möglich ist: 95+ gilt als normal, unter 70 erfordert Maßnahmen.

Die Grundformel lautet: Gesundheits-Score = 100 - Σ(Penalty_i × Gewicht_i). Die Strafen werden nichtlinear berechnet und reagieren auf Trends und Anomalien. Dies ist kein Schwellenwert-Alert – es handelt sich um einen komplexen Indikator, vergleichbar mit Apdex in APM oder EWS in der Medizin.

Kategorienstruktur und Berechnung

Der Gesundheits-Score basiert auf fünf Kategorien mit festen Gewichten. Jede bewertet zentrale Metriken mittels SQL-Abfragen gegen PostgreSQL-Systemansichten.

Google AdInline article slot

Verbindungen (Gewicht 0,20)

Misst die Auslastung des Verbindungspools und Inaktivitätszustände:

SELECT 
    count(*) FILTER (WHERE state = 'active') AS aktive_verbindungen,
    count(*) FILTER (WHERE state = 'idle in transaction') AS idle_in_transaction,
    (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_connections,
    now() - min(xact_start) AS längste_transaktion_alter
FROM pg_stat_activity
WHERE pid != pg_backend_pid();

Die Strafe steigt exponentiell ab 80 % Nutzung. Idle-in-Transaction-Sitzungen älter als 30 Sekunden erhalten eine zusätzliche Strafe, da sie Autovacuum blockieren und zur Bloat beitragen.

Leistung (Gewicht 0,25)

Fokussiert auf die Benutzererfahrung: Cache-Hit-Rate und langsame Abfragen.

Google AdInline article slot
-- Cache-Hit-Rate
SELECT 
    round(100.0 * sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read), 0), 2) AS cache_hit_ratio
FROM pg_statio_user_tables;

-- Langsame Abfragen
SELECT count(*), round(avg(mean_exec_time)::numeric, 2)
FROM pg_stat_statements
WHERE mean_exec_time > 1000 AND calls > 10;

Unter 95 % Hit-Rate löst dies eine Strafe aus; unter 90 % ist es kritisch. Die Ausführungszeit wird gegenüber historischen Baselines verglichen, um Anomalien zu erkennen.

Speicher (Gewicht 0,20)

Überwacht tote Tupel und Bloat:

SELECT 
    schemaname, relname, n_dead_tup, n_live_tup,
    round(100.0 * n_dead_tup / nullif(n_live_tup + n_dead_tup, 0), 2) AS dead_ratio,
    pg_size_pretty(pg_total_relation_size(relid))
FROM pg_stat_user_tables
WHERE n_live_tup + n_dead_tup > 10000
ORDER BY dead_ratio DESC LIMIT 20;

Bloat wird mit pgstattuple oder Heuristiken basierend auf relpages bewertet. Die Festplattennutzung wird gegen Dateisystemgrenzen verglichen.

Google AdInline article slot

Replikation (Gewicht 0,15)

Prüft die Replikationsverzögerung:

SELECT application_name, state, (sent_lsn - replay_lsn) AS lag_bytes,
    write_lag, flush_lag, replay_lag
FROM pg_stat_replication;

Verzögerung über 1 MB oder 5 Sekunden verursacht eine Strafe. Fehlen von Replikaten straft diese Kategorie nicht.

Wartung (Gewicht 0,20)

Verfolgt den Fortschritt von Vacuum und XID-Alter:

-- XID-Alter
SELECT datname, age(datfrozenxid), 2147483648 - age(datfrozenxid)
FROM pg_database ORDER BY age(datfrozenxid) DESC;

-- Vacuum-Alter
SELECT schemaname, relname, now() - greatest(last_vacuum, last_autovacuum) AS vacuum_age
FROM pg_stat_user_tables WHERE n_live_tup > 10000
ORDER BY vacuum_age DESC NULLS FIRST LIMIT 20;

XID-Alter über 1,5 Milliarden löst eine hohe Strafe aus, da das Wraparound-Risiko steigt.

Gewichtslogik und Interpretation

Die Gewichte wurden empirisch gewählt: Leistung liegt mit 0,25 an erster Stelle, da sie direkt die Benutzererfahrung beeinflusst. Verbindungen und Wartung (0,20) sind schnelle Ausfallpunkte. Replikation (0,15) ist optional.

  • 95+: Stabile Zustand.
  • 70–94: Überwachen, Reparaturen planen.
  • 40–69: Sofortige Maßnahmen erforderlich.
  • <40: Incident-Status.

Automatisierte Diagnose mit Empfehlungen

Der Gesundheits-Score enthält eine priorisierte Liste von Problemen:

  • HOCH: Tabelle mit >40 % toten Tupeln und Vacuum älter als 4 Tage — führen Sie VACUUM ANALYZE aus, passen Sie autovacuum_vacuum_scale_factor an.
  • MITTEL: Replikationsverzögerung >500 ms — prüfen Sie die Last des Replikats, wal_receiver_timeout.
  • NIEDRIG: Cache-Hit <99 % — erhöhen Sie shared_buffers auf 25 % des RAM.

Empfehlungen werden über Regeln generiert, einschließlich Prüfung gegen Autovacuum-Schwellenwerte.

SELECT relname, n_dead_tup > (n_live_tup * current_setting('autovacuum_vacuum_scale_factor')::float + current_setting('autovacuum_vacuum_threshold')::float) AS vacuum_due
FROM pg_stat_user_tables;

Wichtige Erkenntnisse

  • Der Gesundheits-Score fasst gewichtete Metriken zusammen und deckt versteckte Kombinationen wie "idle in transaction" + "Bloat" auf, die Schwellenwert-Warnungen verpassen.
  • Die nichtlineare Formel liefert frühzeitige Warnungen vor kritischen Schwellenwerten.
  • Integrierbar mit Prometheus/Grafana über postgres_exporter.
  • Automatisierte Diagnose liefert handlungsorientierte Empfehlungen mit echten SQL-Beispielen.
  • Skalierbar: Vergleicht Trends über die Zeit, um Anomalien zu erkennen.

— Editorial Team

Advertisement 728x90

Weiterlesen