Ja PostgreSQL žurnālā parādās "checkpoints are occurring too frequently", serveris jums saka, ka WAL aizpilda max_wal_size ātrāk, nekā beidzas checkpoint_timeout. Dažas šādas rindas liela pakešdarba laikā ir normālas. Ja tās parādās ik pēc dažām minūtēm parastā slodzē, serveris veic daudz vairāk kontrolpunktu darba, nekā vajag, un lielā, noslogotā datubāzē tas maksā reālu I/O, WAL apjomu un repliku joslas platumu.
Kā ziņojums izskatās
LOG: checkpoints are occurring too frequently (12 seconds apart)
HINT: Consider increasing the configuration parameter "max_wal_size".
Tas ir LOG ziņojums, nevis kļūda, tāpēc nekas neapstājas. PostgreSQL pirmkodā checkpointer to raksta, ja kontrolpunkts pieprasīts WAL apjoma dēļ un sākās mazāk nekā checkpoint_warning sekundes (pēc noklusējuma 30s) pēc iepriekšējā. Iestatījums checkpoint_warning = 0 to izslēdz, bet tas tikai paslēpj simptomu un neko nemaina.
Kāpēc notiek kontrolpunkti
WAL konfigurācijas nodaļa apraksta divus automātiskus izraisītājus, atkarībā no tā, kurš iestājas pirmais:
- Laiks: ik pēc
checkpoint_timeout, pēc noklusējuma 5 minūtes (diapazons no 30 sekundēm līdz vienai dienai). - WAL apjoms: kad drīz tiks pārsniegts
max_wal_size(pēc noklusējuma 1 GB).
Kontrolpunktus var pieprasīt arī tieši, piemēram, ar komandu CHECKPOINT vai bāzes rezerves kopijas sākumā. Mierīgā serverī uzvar taimeris, un kontrolpunkti ir vienmērīgi. Rakstīšanas noslogotā serverī 1 GB WAL var rasties dažās sekundēs, tāpēc izmēra izraisītājs nostrādā atkal un atkal, un parādās brīdinājums.
Kāpēc bieži kontrolpunkti kaitē
- Vairāk WAL, nevis mazāk. Ar
full_page_writes = on(noklusējums un drošais iestatījums) pirmās izmaiņas katrā datu lapā pēc kontrolpunkta ieraksta WAL visu lapu. Dokumentācijā norādīts, ka īsāki intervāli starp kontrolpunktiem palielina WAL apjomu un diska I/O. Karstās lapas pēc katra kontrolpunkta atkal tiek ierakstītas kā pilni attēli. - Ierakstu uzliesmojumi.
checkpoint_completion_target(pēc noklusējuma 0.9) izkliedē netīro lapu ierakstīšanu pa intervālu. Kad intervāls sarūk līdz sekundēm, nav kur izkliedēt, un ieraksti nāk uzliesmojumos, kas konkurē ar vaicājumiem. - Smagāka replikācija un arhivēšana. Katrs papildu pilnas lapas attēls jānosūta uz rezerves serveriem un WAL arhīvu un jāglabā kopā ar rezerves kopijām.
Kompromiss ir atkopšanās pēc avārijas: lielāks attālums starp kontrolpunktiem nozīmē vairāk WAL, kas jāatskaņo pēc avārijas. Tāpēc risinājums ir "pietiekami liels", nevis "pēc iespējas lielāks".
Apstipriniet to ar statistiku un žurnāliem
Pārbaudiet, cik kontrolpunktu bija pieprasīti, nevis laika izraisīti. PostgreSQL 17 kolonnas pārcēla no pg_stat_bgwriter uz pg_stat_checkpointer:
-- PostgreSQL 17 un jaunākas versijas
SELECT num_timed, num_requested,
round(100.0 * num_requested / nullif(num_timed + num_requested, 0), 1) AS pct_requested,
write_time, sync_time, buffers_written, stats_reset
FROM pg_stat_checkpointer;
-- PostgreSQL 16 un vecākas versijas
SELECT checkpoints_timed, checkpoints_req, stats_reset
FROM pg_stat_bgwriter;
Ja kopš stats_reset pieprasītie kontrolpunkti skaidri dominē, max_wal_size ir par mazu jūsu rakstīšanas apjomam. Ņemiet vērā, ka pieprasīto skaitītājā ietilpst arī manuālas CHECKPOINT komandas un bāzes rezerves kopijas, tāpēc nakts rezerves kopēšana pati pievieno dažus.
Kopš PostgreSQL 15 log_checkpoints pēc noklusējuma ir ieslēgts. Katrs kontrolpunkts žurnālā ieraksta rindu checkpoint starting: ar iemeslu (wal, time, immediate, force...) un rindu checkpoint complete: ar ierakstīto buferu skaitu, ierakstīšanas un sinhronizācijas laiku, kā arī distance un estimate kB. Virkne rindu checkpoint starting: wal stāsta to pašu, ko brīdinājums, tikai ar skaitļiem.
Kā izvēlēties max_wal_size
Neminiet. Izmēriet, cik WAL serveris uzraksta viena checkpoint_timeout laikā maksimālās slodzes brīdī:
-- 1. pierakstiet pašreizējo WAL pozīciju maksimālās slodzes laikā
SELECT pg_current_wal_lsn(); -- piem., 3A/1F000000
-- 2. pēc tieši checkpoint_timeout (pēc noklusējuma 5 minūtēm) izmēriet attālumu
SELECT pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), '3A/1F000000'));
-- pilno lapu attēlu daļa WAL (PostgreSQL 14+)
SELECT wal_records, wal_fpi, pg_size_pretty(wal_bytes) FROM pg_stat_wal;
Tad iestatiet max_wal_size ar labu rezervi virs šī skaitļa, lai maksimuma laikā lielāko daļu kontrolpunktu izraisītu laiks un izmēra robežu sasniegtu tikai neparasti lēcieni. Gan max_wal_size, gan checkpoint_timeout var pārlādēt, restartēšana nav vajadzīga:
ALTER SYSTEM SET max_wal_size = '16GB';
SELECT pg_reload_conf();
SHOW max_wal_size;
16GB šeit ir piemērs, nevis ieteikums. Pēc izmaiņām vērojiet pg_stat_checkpointer un kontrolpunktu žurnāla rindas visu biznesa ciklu. Dažas komandas arī palielina checkpoint_timeout līdz 15 vai 30 minūtēm, lai vēl vairāk samazinātu pilnu lapu attēlus; tas pagarina atkopšanos pēc avārijas, tāpēc lemiet to kopā ar atkopšanas laika mērķi.
archive_command, ir liels wal_keep_size vai atpaliek replikācijas slots. Pirms palielināšanas pārliecinieties, ka pg_wal ir vieta jaunajai vērtībai un krietnai rezervei, citādi žurnāla brīdinājumu nomainīsiet pret dīkstāvi, kas aprakstīta rakstā PostgreSQL disks pilns: pg_wal.Kas mainās lielās datubāzēs
- Noklusējuma 1 GB ir niecīgs TB mēroga rakstīšanas slodzei. Noslogota OLTP datubāze vai nakts ETL to var uzrakstīt krietni ātrāk par minūti, tāpēc lielāko daļu kontrolpunktu izraisa izmērs. Rēķinieties ar vērtību desmitos gigabaitu, balstoties uz jūsu pašu WAL apjomu.
- Izvēlieties pg_wal izmēru maksimumam, nevis vidējam. Lielos serveros pg_wal bieži atrodas atsevišķā sējumā. Tam jāietilpina
max_wal_size, arhivēšanas rinda un slotu aizturētais WAL sliktākajā stundā, nevis parastā. - Atkopšanās pēc avārijas kļūst ilgāka. Vairāk WAL starp kontrolpunktiem nozīmē vairāk atskaņošanas pēc avārijas vai pārslēgšanās uz rezerves serveri, kam jāpanāk primārais. Pirms ļoti lielu vērtību izvēles izmēriet atskaņošanas ātrumu uz pilna izmēra kopijas.
- Rezerves serveri seko primārajam. Replikas veic restartpoints, kas iespējami tikai pie primārā kontrolpunktu ierakstiem. Dokumentācija brīdina, ka atkopšanas laikā
max_wal_sizebieži tiek pārsniegts līdz pat viena kontrolpunkta cikla WAL apjomam, tāpēc rezerves serveru diskiem dodiet tādu pašu rezervi. - Liels shared_buffers nozīmē smagākus kontrolpunktus. Ar simtiem gigabaitu buferu katrs kontrolpunkts var izskalot daudz netīro datu. Atstājiet
checkpoint_completion_target0.9, lai tas būtu izkliedēts, un salīdzinietwrite_timeunsync_time, lai redzētu, vai krātuve tiek līdzi. - Pilnu lapu attēli dominē WAL. Salīdziniet
wal_fpiarwal_recordsskatāpg_stat_wal. Ja pilnu lapu attēli ir liela daļa, garāki intervāli starp kontrolpunktiem unwal_compression(lz4vaizstdkopš PostgreSQL 15, ja serveris ar tiem kompilēts) var būtiski samazināt WAL, kas palīdz arī replikām un arhīva krātuvei. Saspiešana patērē CPU, tāpēc pārbaudiet to reālā slodzē. - Lielām ielādēm vajag savu plānu. Atjaunošana un lieli
COPYdarbi rada brīdinājumus pat labi noregulētos serveros. Vienreizējām ielādēm bieži uz laiku palielinamax_wal_size, kā aprakstīts rakstā pg_dump un atjaunošana lielām datubāzēm.
Ko nedarīt
- Neizslēdziet
full_page_writes, lai samazinātu WAL. Dokumentācija brīdina, ka pēc avārijas tas var izraisīt neatgūstamus vai klusus datu bojājumus. - Neiestatiet vienkārši
checkpoint_warning = 0. Kontrolpunkti paliek tikpat bieži. - Neiestatiet
checkpoint_completion_targetuz 1.0. Dokumentācija iesaka ne vairāk kā 0.9.
Galvenās atziņas
- Brīdinājums nozīmē, ka WAL aizpilda
max_wal_sizeātrāk, nekā beidzascheckpoint_timeout. - Bieži kontrolpunkti palielina pilnu lapu attēlus, WAL apjomu, I/O uzliesmojumus un repliku trafiku.
- Salīdziniet pieprasītos un laika kontrolpunktus skatā
pg_stat_checkpointer(17+) vaipg_stat_bgwriter(16 un vecākās). - Izvēlieties
max_wal_sizepēc izmērītā WAL apjoma maksimuma laikā; to var pārlādēt bez restartēšanas. - Lielās datubāzēs jaunajai vērtībai līdzi plānojiet pg_wal vietu, atkopšanas laiku un rezerves serveru rezervi.