Monitoring PostgreSQL

Z PostgreSQL
Skočit na navigaci Skočit na vyhledávání

Autor: Pavel Stěhule

Ať už používáme jakoukoliv databázi, je nutné monitorovat jak databázi, tak databázový server. Dnes si ani nedovedu představit provoz nějaké náročnější aplikace bez základního monitoringu. V praxi se ale setkávám s tím, že dobře nastavený monitoring databáze a databázového serveru je spíše výjimkou, která potvrzuje pravidlo. Opět se pokusím ukázat, že se nejedná o nic komplikovaného a je velká škoda, že se vývojáři připravují o množství nedocenitelných informací, které jim monitoring může přinést.

Asi každá aplikace má lepší nebo horší logování, které je možné využít i pro analýzy výkonu. Monitoring na straně klienta poskytuje pouze část obrazu. V případě výkonnostních problémů nevíme, jestli už vzniká problém v databázi (případně v zdrojích O.S. serveru) nebo až na straně klienta. Z pohledu klienta nevíme, kde na serveru narážíme na limity.

U databázových aplikací je samotná databáze přirozeným úzkým hrdlem, a jakákoliv informace ohledně výkonu je jedna z mála objektivních vyčíslitelných zpětných vazeb pro vývojáře. Bohužel hodně vývojářů netuší, že tyto informace existují, a tak je vůbec nepožadují. Důvodů je několik - někdy nezkušenost, někdy organizační překážky, někdy i osobní averze mezi administrátory a vývojáři. Často je to bludná víra, že databáze si už nějak poradí, a běžný programátor nemá šanci nějak ovlivnit výkon - případně, že to už je práce databázového administrátora a nikoliv programátora. Nic není vzdálenější pravdě.

Výkon aplikace je dán primárně použitou architekturou, potom návrhem interface a použitými algoritmy, dále pak vlastní implementací - skoro až na úplném konci je konfigurace databáze. Databázový administrátor může leccos pokazit, ale už toho nemůže moc zachránit. Co ale může, a měl by, je poskytování zpětné vazby vývojářům. Přeci jen má informace z první ruky - a přeci jen vývojáři by se neměli dostat blízko k produkčním serverům (z mnoha důvodů). Vím o týmech, kde to funguje. Samozřejmě, že jsem viděl i týmy, kde vývojáři obviňují adminy z neschopnosti, a admini vývojáře z pitomosti. To ale žádný výkonnostní problém nevyřeší.

Analýza pomalých dotazů

Prvním nástrojem pro sledování databázového serveru je sledování pomalých dotazů (případně všech dotazů). Téměř v každé aplikaci se objeví dotazy, které server, z nějakého důvodu, nemůže efektivně provést. Ke všemu se často jedná o chybně napsané dotazy - kdy dostaneme nesprávný výsledek a ještě si na něj musíme dlouho počkat. S logem pomalých dotazů se vývojář může zaměřit na několik málo dotazů a ty prověřit po všech stránkách. Pokud se používají ORM systémy, tak log pomalých dotazů je často prvním místem, kde může vývojář vidět dotaz v celku, vidět dobu provádění dotazu a četnost jeho provádění. Když už nic jiného, tak by vývojáři měli používat log pomalých dotazů - je to jednostranná informace, ale už jenom s tím se dá žít. Ne každý pomalý dotaz je možné vyřešit (odstranit). Počítání reportu můžeme zrychlit do určité míry, ale nemůžeme oblafnout fyziku - ať už je to rychlost čtení dat z disků, počet IOPS disků nebo rychlost čtení z operační paměti. O každém pomalém dotazu bychom měli ovšem vědět, a měli bychom vědět, proč je pomalý.

pg_stat_statements

V Postgresu máme pro sledování pomalých dotazů tři nástroje. Nejjednodušším na použití je extenze pg_stat_statements. Ta se instaluje registrací v konfigurační proměnné shared_preload_libraries. Po restartu je nutné ještě extenzi zaregistrovat příkazem CREATE EXTENSION pg_stat_statements v těch databázích, kde chceme mít dostupnou statistiku SQL příkazů.

bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit /
               nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
          FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
-[ RECORD 1 ]---------------------------------------------------------------------
query       | UPDATE pgbench_branches SET bbalance = bbalance + ? WHERE bid = ?;
calls       | 3000
total_time  | 9609.00100000002
rows        | 2836
hit_percent | 99.9778970000200936
-[ RECORD 2 ]---------------------------------------------------------------------
query       | UPDATE pgbench_tellers SET tbalance = tbalance + ? WHERE tid = ?;
calls       | 3000
total_time  | 8015.156
rows        | 2990
hit_percent | 99.9731126579631345
-[ RECORD 3 ]---------------------------------------------------------------------
query       | copy pgbench_accounts from stdin
calls       | 1
total_time  | 310.624
rows        | 100000
hit_percent | 0.30395136778115501520
-[ RECORD 4 ]---------------------------------------------------------------------
query       | UPDATE pgbench_accounts SET abalance = abalance + ? WHERE aid = ?;
calls       | 3000
total_time  | 271.741999999997
rows        | 3000
hit_percent | 93.7968855088209426
-[ RECORD 5 ]---------------------------------------------------------------------
query       | alter table pgbench_accounts add primary key (aid)
calls       | 1
total_time  | 81.42
rows        | 0
hit_percent | 34.4947735191637631

pgFouine

Dalším, dnes už letitým nástrojem je analyzátor logu pomalých dotazů pgFouine - Mně osobně se velice líbí. Generované reporty jsou přehledné, názorné. Dělá to přesně to, co je potřeba. Jedná se ale o aplikaci, která dnes už není udržovaná, a nějakou modernizaci by potřebovala. Výhodou pgFouine je možnost se v reportu podívat na příklady pomalých dotazů a minimální dopad na výkon aplikace.

pgBadger

Moderním a rozvíjený nástroj na zpracování Postgresových logů je pgBadger. Umí z Postgresových logů vyčíst maximum možných informací a poskytuje relativně ucelený náhled na provoz. Pro samotnou analýzu pomalých dotazů mám ale raději jednodušší (skromnější) jednoúčelový pgFouine.

Z logu pomalých dotazů nevyčteme nic o důvodech, proč jsou dotazy pomalé. Jestli v tu dobu bylo zrovna přetížené IO, nebo databáze odbavovala tisíce dotazů za vteřinu nebo naráz prováděla stovky dotazů. Pro plastičtější obraz potřebujeme nástroj pro monitoring operačního systému. Určitě některý znáte: munin, nagios, Grafana.

Zobrazení dalších metrik

Subjektivně mi stále nejvíc vyhovuje munin. Jeho výstupy jsou pro mne dobře čitelné, zřetelné - vyhovuje mi výchozí barevné schéma. Jedná se o poměrně letitý software s určitými muškami - z GoodData vím o výkonnostních problémech při monitoringu větších desítek serverů. Jeho visual je docela archaický - pro každodenní práci ale ocením čitelnost na první pohled. Je úplně jedno, který nástroj používáte. Důležité je mít alespoň jeden monitoring a ten aktivně používat - tj jednou za týden, jednou denně (podle důležitosti aplikace) se na něj podívat, plus samozřejmě v případě problémů.

Zátěž IO

Výkon jakékoliv transakční databáze závisí od stavu IO. IO samozřejmě může mít vliv i na netransakční databáze. Monitorování IO je základ. Je velice praktické sledovat metriky jako je počet IO operací/sec, intenzita zápisu(čtení)/sec, utilizaci IO, případně inverzní hodnotu IO waits. Ve chvíli, kdy máte v databázovém serveru dlouhodobě velké IO waits, tak se razantně prodlužuje zpracování příkazů (z ms i na desítky vteřin).

Využití disků

Další extrémně zajímavou metrikou je obsazenost disků - u dnešních relativně velkých a rychlých disků se doporučuje si udržovat v lepším případě 50% volného místa, v horším případě alespoň 30%. Často je problém s výkonem spojený s nárůstem velikosti databáze - atypicky velký nárůst databáze může signalizovat útok, chyby v čištění, archivaci - v designu skriptů, které realizují upload dat. Ve větších organizacích už nemusí být přehled o všech činnostech, které se dějí na databázovém serveru - upload 100GB databáze hodně zacvičí s IO - při monitoringu uvidíme novou databázi s velkým intenzivním nárůstem. To už stačí k tomu, aby člověk věděl koho se zeptat, případně na co se zeptat.

Spojení do databáze

Zajímavou informací jsou počty spojení - aktivní, neaktivní, čekající na zámek, s otevřenými transakcemi. To hodně říká o designu aplikace, o tom jak náročné jsou dotazy, kde jsou úzká hrdla. Pokud aplikace správně neuvolňuje spojení, neukončuje transakce, tak má neobvykle velké požadavky na počet otevřených spojení do databáze. V grafu počtu spojení je takový problém perfektně vidět.

Nejdelší transakce, nejdelší dotazy, počty transakcí

V SQL databázi zajímavou informací může být graf vykreslující dobu nejdelší aktivní transakce, dobu nejdelšího aktivního dotazu. Zajímavé jsou i počty transakcí. Z nich je vidět, kdy jsou špičky, jak jsou velké - je možné propojit vliv transakcí na zátěž IO. Z počtu transakcí je vidět i dostupnost aplikace. Pokud na Firewallu zaříznete velkého aktivního zákazníka, tak výrazně klesne počet transakcí. Log firewallu běžně nikdo nestuduje - o jednu IP adresu více nebo méně. Propad počtu transakcí je perfektně vidět.

Autovacuum

V PostgreSQL je extrémně důležité vakuování tabulek. Většinu situací řeší automat autovacuum. Tento automat iteruje nad tabulkami, a pokud najde tabulku s 10% změn, tak vytvoří nový proces a v něm spustí příkaz ANALYZE nad tabulkou. V případě tabulky s 20% změn vytvoří nový proces a v něm provede VACUUM tabulky. Počet procesů, které může autovacuum vytvořit je omezený. Je nutné sledovat, jestli je tento limit dostatečný - počet procesů vytvořených automatem nesmí být dlouhodobě na maximu. To by znamenalo, že Postgres nestíhá vacuovat, a docházelo by k zbytečnému nafukování tabulek.

Ostatní

Není od věci si nechat vykreslovat běh delších operací, které mohou mít vliv na zátěž databáze - zálohování, masivní exporty a importy, výpočet fakturace, párování přijatých faktur a plateb. Pokud zjistím například vysokou utilizaci disku, pak si ji mohu jednoduše spojit např. se zálohováním (pokud mám zálohování zobrazené). Tam, kde už na produktu pracuje víc lidí, víc nezávislých týmů je to nedocenitelné.

Závěr

Monitoring je dobré doplnit nástrojem na zpracování logů - občas je nutné provést podrobnější analýzu - a tam už obrázky nestačí. Když se umí zacházet ze splunkem, tak to člověk jen zírá. Dost možná, že na většinu zdejších aplikací by splunk byl tím kanónem na vrabce - postačí Logstash a Elasticsearch. Proti klasickému procházení logů je to neskutečný komfort. Nehledě na to, že opět odstiňuje vývojáře od produkce.

U trochu důležitějších aplikací je vhodné monitoring doplnit alertingem. Dochází místo disku, některá důležitá operace běží neobvykle dlouhou dobu, dochází k několika hodinovému čekání na zámek, k několika hodinovým dotazům, transakcím - to vše může vyžadovat pozornost administrátora. Je hloupé, když Vás na kritické problémy upozorňují uživatelé.

Postavení základního monitoringu databázového serveru je práce na maximálně na půl dne. Fungující monitoring umožňuje vidět problémy, vidět trendy, lépe identifikovat úzká hrdla. S těmito znalostmi lze využít maximálně výkon hardware - nemusíte už pak řešit jestli Vaše aplikace letos přežije předvánoční nákupní šílenství, protože máte dostatek výkonu.