Incidentu reaģēšana

PostgreSQL pilns disks: kāpēc pg_wal aug un kā to droši novērst

Disks ir aizpildīts par 98%, pg_wal ir milzīgs, un kāds jau raksta rm. Apturiet viņu. Kas patiesībā aizpilda PostgreSQL disku, ko drošā veidā var atbrīvot tūlīt un kā panākt, lai tas vairs neatkārtotos.

· 11 min lasīšanai · AG Data komanda

"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

Drošas ārkārtas darbības

  1. 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ļ.
  2. 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.
  3. Novērsiet cēloni: dzēsiet pamesto slotu, izlabojiet arhivēšanu, atceliet nevaldāmo vaicājumu.
  4. 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

Galvenās atziņas

PostgreSQL Pilns disks WAL Incidentu reaģēšana
Sadarbība ar mums

PostgreSQL tieši tagad pietrūkst diska?

Zvaniet +371 20943683 vai rakstiet uz info@agdata.lv. Uz kritiskiem incidentiem pieredzējis DBA reaģē 15 minūšu laikā, 24/7.

Sazināties Vairāk no emuāra