PostgreSQL checkpoint špičky: prečo p99 exploduje každých N minút
Toto je klasický graf, ktorý sa tvári ako záhada:
- CPU stabilné
- throughput relatívne rovný
- ale latencia (hlavne p99) robí periodické špičky – napríklad každých 5 alebo 15 minút
- počas špičiek často rastie disk IO latency
Veľmi často je koreň: checkpoint.
Nie “checkpoint je zlý”, ale checkpoint je mechanizmus, ktorý pri zlej kombinácii konfigurácie a storage spraví z flushovania dirty stránok krátky IO burst. A ten vám zoberie tail latency budget.
Cieľ článku: metodika, ako to reprodukovať, zmerať a vyladiť tak, aby checkpointy prestali byť p99 killer.
Testované na: PostgreSQL 13–16, lokálne NVMe aj cloudové network-attached disky. Príklady používajú Linux nástroje.
Čo checkpoint robí (iba to, čo potrebujete vedieť pre výkon)
Z pohľadu operácií checkpoint znamená:
- Postgres musí garantovať, že určitý “bod v čase” je bezpečne na disku,
- čo v praxi znamená veľa zápisov dirty bufferov,
- a následné fsync/synchronizáciu.
Ak sa tieto zápisy “zhluknú”, uvidíte:
- zvýšenú disk IO latency,
- fronty v storage,
- a následne spomalenie query (aj read-only!) kvôli IO contention.
Metodika: najprv merajte, potom tuning
Minimum signálov, ktoré chcem vidieť
- PostgreSQL štatistiky checkpointov/bgwriter
- WAL tempo (koľko generujete)
- OS disk latency a queue (napr.
iostat) - Latenciu workloadu (pgbench alebo vaše SLI)
SQL: checkpointy a bgwriter
Začnite s pg_stat_bgwriter:
SELECT
checkpoints_timed,
checkpoints_req,
checkpoint_write_time,
checkpoint_sync_time,
buffers_checkpoint,
buffers_clean,
maxwritten_clean,
buffers_backend,
buffers_backend_fsync
FROM pg_stat_bgwriter;
Praktická interpretácia:
checkpoints_timedvscheckpoints_req: akcheckpoints_reqrastie rýchlo, často máte vynútené checkpointy (WAL sa naplní skôr než timeout).checkpoint_write_timeacheckpoint_sync_time: špičky tu často sedia so špičkami p99.
Ak máte PostgreSQL 16+, pg_stat_io pridá viac detailu – ale dobrú diagnózu spravíte aj bez toho.
OS: IO fronty a latencia
Na databázovom node:
iostat -xz 1
Sledujte hlavne:
%util(dlhodobo 100% je zlé znamenie)await/ latenciu (pri špičke vyskočí)- queue indikátory (záleží od platformy)
Reprodukčný lab: naschvál spravte checkpointy bolestivé
Toto robte na test DB, nie na produkcii.
1) Vygenerujte rovnomerný workload
pgbench -i -s 50 mydb
pgbench -c 32 -j 32 -T 300 -P 1 mydb
-P 1 vám dá priebežný output latencie/throughputu.
2) Vynúťte časté checkpointy (len v lab-e)
Pointa labu je:
- spraviť checkpointy častejšie (napr. malý
max_wal_sizealebo kratšícheckpoint_timeout), - a pozorovať, že p99 špičky sa zrovnajú s checkpoint signálmi.
Nekopírujte “magické hodnoty”. Cieľ je pochopiť tvar problému na vašom storage.
3) Korelácia: p99 vs checkpoint signály
Počas testu:
- logujte pgbench latenciu
- odčítajte
pg_stat_bgwriter - sledujte
iostat
Ak špička sedí s checkpoint write/sync časom a IO latenciou na disku, máte vinníka.
“Checkpoint budget”: jednoduchá realita
Aby checkpoint nezabil latenciu, musíte zosúladiť:
- váš write/WAL rate
- s vašou IO kapacitou a latenciou
Ak generujete veľa WAL a máte malé max_wal_size, checkpointy budú časté a často vynútené.
Cieľ tuningovania nie je “najmenej checkpointov”, ale:
- checkpointy, ktoré sú predvídateľné
- a flushing je rozložený v čase
Tuning: čo skúšať (a ako overiť)
1) Znížiť vynútené checkpointy cez WAL sizing
Ak checkpoints_req dominuje, často narazíte na WAL size limit skôr než na timeout.
Smer:
- zvýšiť
max_wal_size(v rámci disk budgetu)
Overenie:
checkpoints_reqspomalí vočicheckpoints_timed- menšie alebo zriedkavejšie p99 špičky
2) Rozložiť zápisy v čase
checkpoint_completion_target pomáha rozložiť checkpoint prácu na väčšiu časť intervalu.
Overenie:
- menej krátkych IO burstov
- hladší
awaitv iostat - menšie p99 špičky
3) Storage realita: niektoré disky majú burst limit
Na cloude je bežné:
- burst výkon, potom throttling.
Ak špičky sedia s throttlingom, DB tuning má limit. Potrebujete:
- lepší disk tier,
- iný disk layout,
- alebo zmenu architektúry (write shaping/batching).
Najčastejšie pasce
Pasca 1: “CPU je v pohode, tak to nie je DB”
Checkpoint špičky sú primárne IO problém. CPU môže byť stabilné.
Pasca 2: “Zvýšime checkpoint_timeout a hotovo”
Môže pomôcť, ale ak vás tlačí max_wal_size, checkpointy budú aj tak vynútené.
Pasca 3: “Tuningujeme query, ale ignorujeme disk queue”
Ak storage je saturovaný, query tuning často nič nevyrieši.
Čo by som spravil v produkcii
- Spravím koreláciu: p99 špičky ↔ checkpoint signály ↔ disk latency
- Skontrolujem
checkpoints_timedvscheckpoints_req - Ak dominujú vynútené checkpointy, riešim WAL sizing a storage limity
- Nastavím checkpoint budget (IO stabilita, predvídateľnosť, alerty)
- Zmeny robím postupne a vždy ich overím meraním
FAQ
Ako zistím, či mám vynútené checkpointy?
Pozrite pg_stat_bgwriter a porovnajte checkpoints_req vs checkpoints_timed.
Prečo checkpoint spomalí aj read-only dotazy?
Lebo čítania čakajú na disk IO. Ak checkpoint spraví IO contention, čítania stoja v rade.
Stačí len zvýšiť max_wal_size?
Nie vždy. Zníži frekvenciu checkpointov, ale ak storage nestíha ani rozložené flushing, potrebujete lepšiu IO kapacitu.
Môže sa to biť s archivingom alebo replikáciou?
Áno. Zmerajte aj WAL tempo a prípadný lag (replication/archiving).
Súvisiace články
/sk/blog/postgresql-wal-forensics/(WAL a čo z neho viete vyčítať)/sk/blog/logical-replication-slot-wal-retention/(WAL retention tlak)/sk/blog/postgresql-autovacuum-slo/(ďalší periodický “p99 killer”)
Further reading
Súvisiace články
Vyčerpanie Connection Poolu: Tichý Spúšťač Výpadkov
Aplikácia visí, ale databáza vyzerá zdravo. Najčastejšie je vyčerpaný connection pool. Ukážem detekciu, rozumné dimenzovanie a prevenciu únikov spojení.
Prometheus native histogramy v produkcii: rollout plán, budgety a failure módy
Prometheus native histogramy vedia odpáliť pamäť, WAL aj remote_write. Návod na postupné nasadenie, budgety a konkrétne queries na verifikáciu.
EXPLAIN vám klamal: PostgreSQL Prepared Statement Plan Cliff
Váš EXPLAIN vyzerá perfektne ale produkcia horí. Vinník: PostgreSQL ticho prepol z custom plánu na generic plán po dostatočnom počte vykonaní, a generic plán je katastrofálne zlý.
Prometheus remote_write backpressure: keď monitoring zaplní disk a ešte aj stratí dáta
Runbook pre výpadky remote_write: ako zmerať lag, odhadnúť time-to-disk-full, bezpečne ladiť queue_config a vedome zvoliť trade-off medzi prežitím a stratou.
Citujte tento článok
Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.