Zpět na domů

Health Score pro PostgreSQL: monitorování zdraví

Health Score pro PostgreSQL agreguje metriky do jednotného skóre od 0 do 100 podle kategorií connections, performance, storage. Odhaluje nebezpečné kombinace a generuje doporučení. Vhodné pro Grafana a Prometheus.

Jednotný Health Score pro PostgreSQL: od 150 metrik k jednomu číslu
Advertisement 728x90

Health Score v PostgreSQL: komplexní ukazatel zdraví databáze

V monitorování PostgreSQL standardní přístup s desítkami dashboardů v Grafaně vede k únavě zobrazení: operátoři ignorují grafy, alerty buď šílí o falešných signálech, nebo se aktivují až příliš pozdě. Health Score řeší tento problém tím, že agreguje více než 150 metrik z pg_stat_* do jediného čísla od 0 do 100. Vzorec berou v úvahu váhy kategorií i nebezpečné kombinace, což umožňuje rychlou hodnocení stavu: 95+ = normální, pod 70 = vyžaduje akci.

Základní vzorec: Health Score = 100 - Σ(penalty_i × weight_i). Tresty se počítají nelineárně, reagují na trendy a anomálie. Jedná se ne o prahový alarm, ale o kompozitní indikátor podobný Apdex v APM nebo EWS ve medicíně.

Struktura kategorií a výpočty

Health Score je postaven na pěti kategoriích s pevnými váhami. Každá kategorie analyzuje klíčové metriky prostřednictvím SQL dotazů k systémovým pohledům PostgreSQL.

Google AdInline article slot

Connections (váha 0,20)

Hodnotí zátěž spojení a stavy idle:

SELECT 
    count(*) FILTER (WHERE state = 'active') AS active_connections,
    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 longest_transaction_age
FROM pg_stat_activity
WHERE pid != pg_backend_pid();

Trest roste exponenciálně po dosažení 80 % zátěže. Idle in transaction starší než 30 sekund je samostatný trest, protože blokuje autovacuum a hromadí bloat.

Performance (váha 0,25)

Zaměřuje se na uživatelský zážitek: poměr hitu mezi cache a pomalé dotazy.

Google AdInline article slot
-- Poměr hitu cache
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;

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

Poměr nižší než 95 % – trest, nižší než 90 % – kritické. Čas provádění se porovnává s historickým základním úrovněm pro detekci anomálií.

Storage (váha 0,20)

Monitoruje mrtvé řádky a 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 se hodnotí pomocí pgstattuple nebo heuristiky podle relpages. Použití disku se porovnává s limity FS.

Google AdInline article slot

Replication (váha 0,15)

Ověřuje zpoždění replik:

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

Zpoždění >1 MB nebo >5 s – trest. Chybějící repliky kategorii neštrafují.

Maintenance (váha 0,20)

Kontroluje vacuum a věk XID:

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

-- Věk vacuum
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;

Věk XID >1,5 miliardy – vysoký trest kvůli riziku wraparound.

Logika vah a interpretace

Váhy byly zvoleny empiricky: Performance vedoucí (0,25), protože přímo ovlivňuje UX. Connections a Maintenance (0,20) – rychlé/možné zabijáky. Replication (0,15) – volitelné.

  • 95+: stabilní stav.
  • 70–94: sledovat, plánovat opravy.
  • 40–69: okamžité akce.
  • <40: incident.

Automatická diagnostika s doporučeními

Health Score je doplněn prioritním seznamem problémů:

  • HIGH: Tabulka s mrtvými řádky >40 %, vacuum >4 dní – spustit VACUUM ANALYZE, upravit autovacuum_scale_factor.
  • MEDIUM: Zpoždění replikace >500 ms – zkontrolovat zátěž repliky, wal_receiver_timeout.
  • LOW: Poměr hitu cache <99 % – zvýšit shared_buffers na 25 % RAM.

Doporučení jsou generována podle pravidel, včetně kontroly prahových hodnot autovacuum.

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;

Co je důležité

  • Health Score agreguje metriky s váhami, identifikuje kombinace jako idle in transaction + bloat, které jsou pro prahové alerty neviditelné.
  • Vzorec je nelineární: raná varování před kritickými prahy.
  • Integrace s Prometheus/Grafana: export přes postgres_exporter.
  • Automatická diagnostika poskytuje konkrétní doporučení s ukázkami SQL.
  • Škálovatelné: porovnání trendů z historie pro detekci anomálií.

— Editorial Team

Advertisement 728x90

Číst dál