Powrót do strony głównej

Health Score dla PostgreSQL: monitorowanie zdrowia

Health Score dla PostgreSQL agreguje metryki w jednolity wynik od 0 do 100 w kategoriach connections, performance, storage. Wykrywa niebezpieczne kombinacje i generuje rekomendacje. Nadaje się dla Grafana i Prometheus.

Jednolity Health Score dla PostgreSQL: od 150 metryk do jednej liczby
Advertisement 728x90

Wskaźnik zdrowia w PostgreSQL: zintegrowany wskaźnik stanu bazy danych

Standardowy podejście do monitorowania PostgreSQL z dziesiątkami paneli w Grafana prowadzi do zmęczenia przez dashboardy: operatorzy ignorują wykresy, a alarmy albo spamują fałszywymi sygnałami, albo aktywują się zbyt późno. Wskaźnik zdrowia rozwiązuje ten problem, agregując ponad 150 metryk z pg_stat_* w jedno liczbowe oznaczenie od 0 do 100. Formuła uwzględnia wagi kategorii i niebezpieczne kombinacje, umożliwiając szybką ocenę stanu: 95+ to norma, poniżej 70 — wymaga działania.

Podstawowa formuła: Wskaźnik zdrowia = 100 - Σ(puni_i × waga_i). Puni są obliczane nieliniowo, reagując na trendy i anomalie. To nie jest prosty alarm progu, ale zintegrowany wskaźnik podobny do Apdex w APM lub EWS w medycynie.

Struktura kategorii i obliczenia

Wskaźnik zdrowia opiera się na pięciu kategoriach z ustalonymi wagami. Każda kategoria analizuje kluczowe metryki za pomocą zapytań SQL do systemowych widoków PostgreSQL.

Google AdInline article slot

Połączenia (waga 0.20)

Ocenia stopień wypełnienia puli połączeń oraz stany bezczynności:

SELECT 
    count(*) FILTER (WHERE state = 'active') AS aktywne_połączenia,
    count(*) FILTER (WHERE state = 'idle in transaction') AS bezczynne_w_transakcji,
    (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS maksymalne_połączenia,
    now() - min(xact_start) AS najdłuższa_trwająca_transakcja
FROM pg_stat_activity
WHERE pid != pg_backend_pid();

Puni rosną wykładniczo po przekroczeniu 80% obciążenia. Bezczynność w transakcji dłużej niż 30 sekund to osobny punkt kar, ponieważ blokuje autovacuum i powoduje narastanie bloatu.

Wydajność (waga 0.25)

Skupia się na doświadczeniu użytkownika: współczynnik trafień w cache i powolne zapytania.

Google AdInline article slot
-- Współczynnik trafień w cache
SELECT 
    round(100.0 * sum(heap_blks_hit) / nullif(sum(heap_blks_hit) + sum(heap_blks_read), 0), 2) AS współczynnik_trafien_w_cache
FROM pg_statio_user_tables;

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

Współczynnik trafień poniżej 95% — puni, poniżej 90% — krytyczne. Czas wykonania porównywany jest z historycznym poziomem bazowym, aby wykryć anomalie.

Przechowywanie (waga 0.20)

Monitoruje martwe tuple i 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 stosunek_martwych,
    pg_size_pretty(pg_total_relation_size(relid))
FROM pg_stat_user_tables
WHERE n_live_tup + n_dead_tup > 10000
ORDER BY stosunek_martwych DESC LIMIT 20;

Bloat oceniany przez pgstattuple lub heurystykę opartą na relpages. Użycie dysku porównywane z limitami systemu plików.

Google AdInline article slot

Replikacja (waga 0.15)

Sprawdza opóźnienie replikacji:

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

Opóźnienie >1 MB lub >5 sekund — puni. Brak replik nie karze tej kategorii.

Konserwacja (waga 0.20)

Kontroluje vacuum i wiek XID:

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

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

Wiek XID >1,5 mld — wysoki puni ze względu na ryzyko wraparound.

Logika wag i interpretacja

Wagi wybrane empirycznie: Wydajność lideruje (0.25), ponieważ bezpośrednio wpływa na UX. Połączenia i Konserwacja (0.20) — szybkie/powolne zabójcy. Replikacja (0.15) — opcjonalna.

  • 95+: stabilny stan.
  • 70–94: monitorować, planować naprawy.
  • 40–69: natychmiastowe działania.
  • <40: incydent.

Diagnostyka automatyczna z zaleceniami

Wskaźnik zdrowia uzupełniony jest priorytetowym listą problemów:

  • WYSOKI: tabela z martwymi tuple >40%, vacuum >4 dni — uruchomić VACUUM ANALYZE, dostosować autovacuum_scale_factor.
  • ŚREDNI: opóźnienie replikacji >500 ms — sprawdzić obciążenie repliki, wal_receiver_timeout.
  • NISKI: współczynnik trafień <99% — zwiększyć shared_buffers do 25% RAM.

Zalecenia generowane są na podstawie reguł, w tym sprawdzania progów autovacuum.

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

Co jest ważne

  • Wskaźnik zdrowia agreguje metryki z wagami, wykrywając kombinacje jak np. bezczynność w transakcji + bloat, które są niewidoczne dla alarmów progu.
  • Formuła nieliniowa: wczesne ostrzeżenia przed osiągnięciem krytycznych progów.
  • Integracja z Prometheus/Grafana: eksport przez postgres_exporter.
  • Diagnostyka automatyczna daje działające zalecenia z przykładami SQL.
  • Skalowalność: porównanie trendów z historią do wykrywania anomalii.

— Editorial Team

Advertisement 728x90

Czytaj dalej