"PostgreSQL pilns disks" ir viena no biežākajām datubāzu ārkārtas situācijām un viena no tām, ko visvieglāk padarīt vēl sliktāku. Disks sasniedz 100%, ieraksti neizdodas, un, paskatoties apkārt, lielākā direktorija ir pg_wal. Failu dzēšana no tās šķiet acīmredzams risinājums. Tā ir vienīgā lieta, ko darīt nedrīkst. Lūk, kas patiesībā aizpilda disku, kā atbrīvot vietu, nesabojājot datubāzi, un kā panākt, lai tas neatkārtotos.
Kas notiek, kad PostgreSQL pietrūkst diska
Tas atkarīgs no tā, kura failu sistēma piepildās. Ja tā ir tā, kurā atrodas pg_wal, PostgreSQL nevar rakstīt WAL un izslēdzas. PostgreSQL dokumentācija to apraksta tieši: ja šī failu sistēma piepildās, "PostgreSQL will do a PANIC shutdown. No committed transactions will be lost, but the database will remain offline until you free some space" (PostgreSQL veiks PANIC izslēgšanos, apstiprinātās transakcijas netiks zaudētas, bet datubāze paliks bezsaistē, līdz atbrīvosiet vietu).
Izlasiet to vēlreiz, jo tā ir labā ziņa: apstiprinātie dati ir drošībā. Dīkstāve ir saistīta ar vietu, nevis ar bojājumu. Stāsti par datu zudumu sākas vēlāk, kad kāds atbrīvo vietu, dzēšot nepareizos failus.
Pirmais noteikums: nekad nedzēsiet failus no pg_wal ar roku
WAL faili, ko PostgreSQL joprojām glabā, tiek glabāti ar iemeslu: atkopšanai pēc avārijas, arhivēšanai vai replikai, kurai tie vēl vajadzīgi. Izdzēsiet tos manuāli, un varat palikt ar klasteri, kas nestartē, salauztu repliku vai rezerves kopiju ķēdi ar caurumu. Tas pats attiecas uz pg_xact un jebko citu datu direktorijā. PostgreSQL vecos WAL failus izņem pats, tiklīdz tie nevienam vairs nav vajadzīgi. Jūsu uzdevums ir noskaidrot, kāpēc kaut kam tie joprojām ir vajadzīgi.
1. solis: atrodiet, kas patiesībā aizņem vietu
du -sh /var/lib/postgresql/*/main/* | sort -h | tail
df -h
(Pielāgojiet ceļu savai datu direktorijai.) Parasti redzēsiet vienu no trim ainām: milzīgs ir pg_wal, milzīgs ir base (pašas tabulas), vai vieta aizņemta pavisam ārpus datu direktorijas.
Ja pg_wal ir milzīgs: četri biežākie cēloņi
1. Replikācijas slots, kuru neviens nelasa
Replikācijas slots garantē, ka WAL tiek glabāts, līdz tā patērētājs to ir saņēmis. Ja patērētāja vairs nav (izdzēsta replika, izslēgts CDC rīks, aizmirsts loģiskās replikācijas abonents), WAL uzkrājas bezgalīgi. Pēc noklusējuma to nekas neaptur: max_slot_wal_keep_size ir -1, kas nozīmē, ka sloti drīkst paturēt neierobežotu WAL failu apjomu (replikācijas iestatījumi).
SELECT slot_name, slot_type, active, wal_status,
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained
FROM pg_replication_slots
ORDER BY pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) DESC;
Neaktīvs slots, kas aiztur simtiem gigabaitu, ir jūsu atbilde. Ja esat pārliecināti, ka neviens to vairs neizmantos, dzēsiet to ar SELECT pg_drop_replication_slot('name');, un PostgreSQL nākamajā kontrolpunktā iztīrīs WAL. Ja tas pieder replikai, kas jums joprojām vajadzīga, šo repliku vēlāk nāksies pārbūvēt vai pieslēgt no jauna. Tas ir lēmums tās īpašniekam, tāpēc pirms dzēšanas pajautājiet.
2. WAL arhivēšana neizdodas
Kad archive_command (vai arhivēšanas bibliotēka) neizdodas, PostgreSQL turpina mēģināt un patur katru segmentu, kas nav arhivēts. Dokumentācija brīdina, ka pg_wal turpinās pildīties ar WAL segmentu failiem, līdz situācija tiks atrisināta. Tipiski iemesli: beigušies rezerves kopiju krātuves piekļuves dati, arhīva mērķis ir pilns, vai rīks atjaunināts un komanda mainījusies.
SELECT archived_count, last_archived_wal, last_archived_time,
failed_count, last_failed_wal, last_failed_time
FROM pg_stat_archiver;
Augošs failed_count un vecs last_archived_time to apstiprina. Pārbaudiet arī PostgreSQL žurnālā faktisko kļūdu: dokumentācijā norādīts, ka dažas kļūmes, piemēram, "command not found", liek arhivētājam pārstartēties un pg_stat_archiver vispār netiek uzrādītas. Izlabojiet komandu, un uzkrājums iztukšosies pats. Nelabojiet to, iestatot archive_command uz kaut ko, kas vienmēr "izdodas", neko nearhivējot: disks atbrīvosies, bet jūs klusi salauzīsiet atjaunošanu uz noteiktu laika brīdi (PITR).
3. Replika, kas stipri atpalikusi
Ja wal_keep_size ir iestatīts liels, primārais serveris patur tik daudz WAL rezerves serveriem. Desmitiem gigabaitu "katram gadījumam" uz neliela diska ir izplatīts veids, kā to piepildīt.
4. Lieli ierakstu pīķi un kontrolpunkti
Liela datu ielāde, masveida UPDATE vai indeksa pārbūve var radīt WAL ātrāk, nekā kontrolpunkti to pārstrādā, īpaši ar lielu max_wal_size. Šāds pieaugums parasti ir īslaicīgs, bet uz šaura diska ar īslaicīgu pietiek.
Ja vieta aizņemta citur
- Pagaidu faili. Nevaldāms vaicājums, kas kārto vai hešo milzīgu datu kopu, var ierakstīt desmitiem gigabaitu direktorijā
base/pgsql_tmp. Vaicājuma atcelšana tos atbrīvo. Ieslēdzietlog_temp_files, lai redzētu, kas to dara, un iestatiettemp_file_limit, lai to ierobežotu. - Servera žurnāli. Žurnāls, kas pilns ar atkārtotām kļūdām, vai pēc atkļūdošanas ieslēgts atstāts
log_statement = 'all'var augt ļoti ātri. - Tabulu un indeksu uzpūšanās. Ja
baseaug ātrāk nekā jūsu dati, autovacuum netiek līdzi. Tam vajag pielāgošanu, nevis ātru labojumu (skatiet mūsu autovacuum pielāgošanas ceļvedi). - Lietas, kurām tur nav vietas. Veci
pg_dumpfaili, pagājušā gada atjaunināšanas laikā izveidota datu direktorijas kopija, core dump faili. Tos droši var pārvietot citur, kad esat pārbaudījuši, kas tie ir.
Drošas ārkārtas darbības
- Palieliniet sējumu. Lielākajā daļā mākoņu disku var paplašināt tiešsaistē dažu minūšu laikā. Bieži tas ir ātrākais un drošākais ceļš atpakaļ.
- Atbrīvojiet vietu ārpus datu direktorijas: veci žurnāli, dump faili, pakotņu kešatmiņa. Ja neesat pārliecināti, pārvietojiet, nevis dzēsiet.
- Novērsiet cēloni: dzēsiet pamesto slotu, izlabojiet arhivēšanu, atceliet nevaldāmo vaicājumu.
- Startējiet PostgreSQL un ļaujiet tam atkopties. Tas atskaņo WAL un pēc tam kontrolpunktos izņem to, kas vairs nav vajadzīgs.
Daudzas komandas datubāzes sējumā tur dažus gigabaitus lielu "balasta" failu, kas izveidots ar fallocate. Kad disks piepildās, tā dzēšana uzreiz dod elpas brīvību, lai startētu serveri un novērstu īsto cēloni. Tas maksā nedaudz diska vietas un var ietaupīt stundu panikas.
Ja PostgreSQL nestartē pat ar brīvu vietu vai redzat kļūdas par trūkstošiem WAL failiem, pārtrauciet eksperimentus. Tas ir brīdis piesaistīt pieredzējušu DBA, un mūsu ārkārtas DBA ceļvedis paskaidro, ko sagatavot.
Kā panākt, lai tas neatkārtotos
- Ierobežojiet replikācijas slotus ar
max_slot_wal_keep_size. Slots, kas to pārsniedz, var zaudēt savu WAL, un tā patērētājs būs jāsinhronizē no jauna, bet primārais serveris paliek darbā. Tas gandrīz vienmēr ir labāks kompromiss. - PostgreSQL 18 apsveriet
idle_replication_slot_timeout, kas padara nederīgus slotus, kuri bijuši neaktīvi ilgāk par iestatīto laiku. Pēc noklusējuma tas ir izslēgts. - Uzraugiet arhivētāju: brīdiniet, ja
failed_countaug unlast_archived_timekļūst vecs. - Uzraugiet slotus: neaktīvus slotus un kolonnu
wal_statusskatā pg_replication_slots. - Brīdiniet par diska lietojuma tendencēm, ne tikai sliekšņiem. 80%, kas aug par 5% stundā, ir steidzamāk nekā 90%, kas nemainās. Diska pieaugums ir viens no signāliem mūsu sarakstā datubāzu rādītāji, kas paredz incidentus.
- Ja iespējams, nodaliet WAL un žurnālus no datiem, lai viena nevaldāma problēma nevarētu paņemt līdzi visu.
Galvenās atziņas
- Kad WAL failu sistēma piepildās, PostgreSQL izslēdzas, bet apstiprinātie dati ir drošībā. Nepārvērtiet dīkstāvi datu zudumā.
- Nekad nedzēsiet failus
pg_walar roku. Noskaidrojiet, kāpēc PostgreSQL tos patur. - Biežākie vaininieki ir pamests replikācijas slots, neveiksmīga WAL arhivēšana, liels
wal_keep_size, pagaidu faili un žurnāli. - Ātrākais drošais labojums: palieliniet sējumu, atbrīvojiet vietu ārpus datu direktorijas, tad novērsiet cēloni.
- Novērsiet atkārtošanos ar
max_slot_wal_keep_size, arhivētāja un slotu monitoringu un diska tendenču brīdinājumiem.