Duomenų bazių administratoriams (DBA) ir „DevOps“ inžinieriams, valdantiems „PostgreSQL“ gamybinėje aplinkoje, artimo nuliniam atkūrimo taško tikslo (RPO) pasiekimas yra pagrindinis reikalavimas. „PostgreSQL“ avarinio atkūrimo ir atkūrimo tam tikru laiko momentu (PITR) galimybių pagrindas yra „Write-Ahead Logging“ (WAL) žurnalai. Nors WAL užtikrina ACID atitiktį, registruodamas operacijas prieš joms patenkant į duomenų failus, WAL archyvavimas yra mechanizmas, kuris išsaugo šiuos žurnalus ilgalaikiam atsarginiam kopijavimui ir replikacijai.
Tačiau WAL archyvavimo konfigūravimas nėra vienkartinis veiksmas. Netinkamos konfigūracijos, tylūs gedimai ir architektūriniai nesusipratimai gali sukelti katastrofišką duomenų praradimą, „split-brain“ scenarijus ar visišką duomenų bazės neveikimą.
Šiame išsamiame vadove išnagrinėsime „PostgreSQL“ WAL archyvavimo architektūrą, nustatysime dažniausiai pasitaikančias klaidas, vedančias į duomenų praradimą, ir apibrėžsime gamybinio lygio geriausias praktikas, užtikrinančias jūsų duomenų bazės atsparumą.
„PostgreSQL“ WAL architektūros supratimas
Prieš gilinantis į klaidas, svarbu suprasti, kaip „PostgreSQL“ tvarko operacijų žurnalus.
„PostgreSQL“ visus pakeitimus įrašo į WAL segmentus (numatytasis dydis – 16 MB), esančius pg_wal kataloge (anksčiau pg_xlog, versijose iki 10). Kiekviena operacija įrašoma nuosekliai ir pažymima žurnalo sekos numeriu (LSN).
Kai WAL segmentas užsipildo, „PostgreSQL“ perjungia jį į naują. Kad pg_wal katalogas neaugtų be galo, „PostgreSQL“ perdirba arba pašalina senus WAL segmentus, kai jų nebereikia avarinio atkūrimo ar replikacijos tikslais.
WAL archyvavimas perima šį perdirbimo procesą. Kai įjungtas archive_mode, „PostgreSQL“ vykdo vartotojo apibrėžtą archive_command (arba naudoja archive_library „PostgreSQL 15+“ versijose), kad nukopijuotų užbaigtą WAL segmentą į saugią, antrinę vietą prieš jį ištrinant ar perrašant.
Norint atlikti atkūrimą tam tikru laiko momentu (PITR), reikia dviejų komponentų:
1. Galiojančios bazinės atsarginės kopijos.
2. Nenutrūkstamos archyvuotų WAL failų grandinės nuo bazinės atsarginės kopijos sukūrimo momento iki tikslinio atkūrimo laiko.
Jei ši WAL grandinė nutrūksta, jūsų PITR nepavyks.
WAL archyvavimo konfigūravimas gamybinei aplinkai
Norėdami įjungti WAL archyvavimą, turite modifikuoti postgresql.conf failą. Pagrindinei konfigūracijai reikia nustatyti wal_level, įjungti archive_mode ir apibrėžti archive_command.
# postgresql.conf
wal_level = replica # archyvavimui reikalingas 'replica' arba 'logical'
archive_mode = on # įjungia archyvavimo procesą
archive_command = 'test ! -f /mnt/nfs/archive/%f && cp %p /mnt/nfs/archive/%f'
archive_timeout = 600 # priverstinis WAL perjungimas kas 10 minučių
archive_command komandoje:
* %p nurodo visą kelią iki archyvuojamo WAL failo.
* %f nurodo WAL failo pavadinimą.
Nors aukščiau pateikta konfigūracija atrodo paprasta, pasikliovimas paprastomis apvalkalo (shell) komandomis įmonių aplinkoje kelia didelę riziką.
Dažniausios WAL archyvavimo klaidos
1 klaida: „Tylus sėkmingas vykdymas“ naudojant archive_command
„PostgreSQL“ visiškai pasikliauja archive_command išėjimo kodu. Jei komanda grąžina 0, „PostgreSQL“ daro prielaidą, kad WAL failas saugiai archyvuotas, ir tęsia originalaus failo perdirbimą.
Dažna klaida yra naudoti komandą, kuri grąžina 0 net tada, kai duomenys nėra saugiai įrašyti į nuolatinę saugyklą. Pavyzdžiui, paprasta cp komanda gali grąžinti sėkmę, kai tik duomenys patenka į OS puslapių talpyklą (page cache) paskirties serveryje. Jei paskirties serveris praranda maitinimą prieš talpyklai įrašant duomenis į diską, WAL failas prarandamas, o „PostgreSQL“ jau ištrynė savo vietinę kopiją.
Rizika: Nutrūkusi WAL grandinė ir negalėjimas atlikti PITR, kas paaiškėja tik avarinio atkūrimo metu.
Sprendimas: Užtikrinkite, kad jūsų archyvavimo scenarijus reikalautų sinchroninio įrašymo. Jei naudojate standartines apvalkalo komandas, pasitelkite įrankius, garantuojančius duomenų įrašymą, arba parašykite papildomą scenarijų, kuris po perkėlimo patikrina failo dydį ir kontrolinę sumą.
2 klaida: pg_wal skaidinio išsekimas (WAL išsipūtimas)
Jei archive_command nepavyksta (grąžinamas ne nulinis kodas) dėl tinklo sutrikimų, neteisingų teisių ar pilno paskirties disko, „PostgreSQL“ išlaikys WAL failą pg_wal kataloge ir bandys pakartoti komandą neribotą laiką.
Nors tai apsaugo nuo duomenų praradimo nešalinant nearchyvuotų WAL failų, tai sukelia rimtą prieinamumo riziką. Jei pg_wal katalogas yra skaidinyje, kuris užsipildo iki 100 %, „PostgreSQL“ išleis PANIC pranešimą ir „nulūš“. Duomenų bazė nepasileis, kol nebus atlaisvinta vietos.
Rizika: Visiškas duomenų bazės neveikimas dėl pilno pg_wal skaidinio.
Sprendimas:
1. Visada talpinkite pg_wal atskirame disko skaidinyje.
2. Įdiekite aktyvų pg_wal katalogo dydžio stebėjimą.
3. Stebėkite pg_stat_archiver rodinį, kad nedelsiant aptiktumėte nepavykusias archyvavimo komandas.
3 klaida: Nepilnos bazinės atsarginės kopijos
Bazinė atsarginė kopija yra bevertė be WAL failų, sugeneruotų atsarginės kopijos kūrimo metu. Jei darote failų sistemos lygio momentinę kopiją (snapshot) arba naudojate pg_basebackup be WAL srautinio perdavimo (-X stream), turite užtikrinti, kad WAL failai, sugeneruoti tarp atsarginės kopijos pradžios ir pabaigos, būtų sėkmingai archyvuoti.
Jei jūsų archyvavimo procesas vėluoja arba nepavyksta, o tie konkretūs WAL failai prarandami, bazinė atsarginė kopija negali būti atkurta į nuoseklią būseną.
Rizika: Sugadintos arba neatkuriamos bazinės atsarginės kopijos.
Sprendimas: Naudokite pg_basebackup -X stream, kad įtrauktumėte reikiamus WAL failus į pačią atsarginę kopiją, arba naudokite įmonių lygio atsarginių kopijų sprendimus, kurie automatiškai valdo priklausomybę tarp bazinių kopijų ir WAL segmentų.
4 klaida: Laiko juostų (Timeline) painiava ir „split-brain“ scenarijai
Kai budintis (standby) serveris paaukštinamas iki pagrindinio, „PostgreSQL“ padidina „Timeline ID“ (pirmoji WAL failo pavadinimo dalis, pvz., 0000000200000001000000A4). Tai neleidžia naujam pagrindiniam serveriui perrašyti senojo pagrindinio serverio WAL istorijos.
Tačiau, jei senasis pagrindinis serveris netyčia paleidžiamas be tinkamo atskyrimo (fencing) („split-brain“ scenarijus), jis gali bandyti siųsti WAL failus į tą pačią archyvavimo vietą naudodamas seną laiko juostą. Jei jūsų archive_command aklai perrašo failus, galite sugadinti savo archyvų saugyklą.
Rizika: Perrašyti WAL failai, sugadinti archyvai ir neatkuriamos duomenų bazės.
Sprendimas: Jūsų archive_command niekada neturi perrašyti egzistuojančio failo. Atkreipkite dėmesį į ankstesnę pagrindinę konfigūraciją, kurioje naudojome test ! -f /mnt/nfs/archive/%f, kad komanda aiškiai nepavyktų, jei failas jau egzistuoja.
Duomenų praradimo rizikos mažinimas: gamybinės geriausios praktikos
Norėdami sustiprinti savo „PostgreSQL“ archyvavimo strategiją, įgyvendinkite šias geriausias praktikas.
1. Stebėkite archyvavimo procesą natyviai
„PostgreSQL“ pateikia įmontuotą rodinį pg_stat_archiver, kuris seka jūsų archyvavimo proceso sėkmę ir nesėkmes. Turėtumėte integruoti šį rodinį į savo stebėjimo sistemą (pvz., „Prometheus“, „Datadog“ ar „Zabbix“).
SELECT
archived_count,
last_archived_wal,
last_archived_time,
failed_count,
last_failed_wal,
last_failed_time,
stats_reset
FROM pg_stat_archiver;
Konfigūruotinos įspėjimų ribos:
* Įspėti, jei didėja failed_count.
* Įspėti, jei laiko skirtumas tarp now() ir last_archived_time viršija jūsų RPO ribą (pvz., 15 minučių), atsižvelgiant į tai, kad mažo srauto duomenų bazėse gali natūraliai kilti vėlavimų, nebent nustatytas archive_timeout.
2. Pasinaudokite archive_timeout
Duomenų bazėse su mažu įrašymo kiekiu 16 MB WAL failas gali pildytis valandų valandas. Kol jis neužsipildo, jis nearchyvuojamas. Jei serveris „nulūžta“ ir vietinis diskas prarandamas, prarandate valandų operacijas.
Nustačius archive_timeout = 600 (10 minučių), „PostgreSQL“ priverčiamas perjungti į naują WAL failą ir archyvuoti dabartinį, net jei jis nėra pilnas. Tai garantuoja, kad jūsų RPO neviršys 10 minučių, šiek tiek padidinant saugyklos naudojimą dėl iš dalies užpildytų WAL failų.
3. Perėjimas prie archive_library („PostgreSQL 15+“)
Istoriškai archive_command kiekvienam WAL failui sukurdavo naują apvalkalo procesą. Didelio našumo aplinkose, generuojančiose šimtus WAL failų per minutę, apvalkalo procesų kūrimo sąnaudos tampa našumo kliūtimi.
„PostgreSQL 15“ pristatė archive_library parametrą, leidžiantį WAL archyvavimą tvarkyti dinamiškai įkeliamiems C moduliams. Tai pašalina apvalkalo procesų kūrimo sąnaudas ir suteikia daug patikimesnį, didelio našumo archyvavimo mechanizmą. Jei naudojate „PostgreSQL 15“ ar naujesnę versiją, ieškokite atsarginių kopijų įrankių, palaikančių pasirinktinius archyvavimo modulius.
4. Reguliariai testuokite atkūrimą tam tikru laiko momentu (PITR)
Neišbandyta atsarginė kopija nėra atsarginė kopija; tai tik viltis. Vienintelis būdas patikrinti, ar jūsų WAL archyvavimas veikia teisingai, ar WAL grandinė nenutrūkusi ir ar bazinės atsarginės kopijos yra nuoseklios, yra atlikti reguliarius, automatizuotus PITR testus.
Paleiskite laikiną egzempliorių, atkurkite bazinę atsarginę kopiją, sukonfigūruokite restore_command, kad duomenys būtų traukiami iš jūsų archyvo, ir atkurkite iki konkretaus laiko momento. Patikrinkite, ar duomenų bazė pasiekia nuoseklią būseną ir priima prisijungimus.
Įmonių lygio atsarginės kopijos ir atkūrimas su „CloudSave“
Pasirinktinių apvalkalo scenarijų valdymas archive_command komandai, WAL dublikatų šalinimas ir saugios, nutolusios saugyklos užtikrinimas operacijų žurnalams gali greitai tapti IT komandų našta.
Čia „CloudSave“ suteikia didelę vertę įmonių „PostgreSQL“ aplinkoms. „CloudSave“ tiesiogiai integruojasi su „PostgreSQL“ natyviomis atsarginių kopijų ir WAL archyvavimo API, kad pašalintų aukščiau aptartas rankines klaidas.
Vietoj trapių „bash“ scenarijų rašymo, „CloudSave“ suteikia patikimą, agentu pagrįstą arba agento nereikalaujančią integraciją, kuri:
* Garantuoja pristatymą: Pakeičia standartines apvalkalo komandas patikrintais, kontrolinių sumų validuojamais perkėlimais į saugią nutolusią arba debesų saugyklą.
* Apsaugo nuo WAL išsipūtimo: Aktyviai stebi pg_wal katalogą ir įspėja administratorius gerokai prieš skaidinio išsekimą.
* Automatizuoja PITR: Supaprastina atkūrimą tam tikru laiko momentu per intuityvią sąsają. Jūs pasirenkate tikslią minutę, iki kurios norite atkurti, o „CloudSave“ automatiškai surenka reikiamą bazinę atsarginę kopiją ir srautu perduoda tikslią WAL failų seką, reikalingą tai būsenai pasiekti.
* Tvarko laiko juostas: Išmaniai valdo „PostgreSQL“ laiko juostų istorijas, užtikrindama, kad perjungimai ir „split-brain“ scenarijai nesugadintų jūsų atsarginių kopijų saugyklos.
Perleisdami sunkų WAL valdymo darbą „CloudSave“, DBA gali susikoncentruoti į užklausų optimizavimą ir duomenų bazės našumą, žinodami, kad jų RPO ir RTO SLA yra apsaugoti įmonių lygio platformos.
Išvada
„PostgreSQL“ WAL archyvavimas yra duomenų bazės avarinio atkūrimo stuburas. Nors failo kopijavimo iš vieno katalogo į kitą koncepcija atrodo paprasta, kraštutiniai atvejai – tylūs gedimai, disko išsekimas ir laiko juostų nukrypimai – kelia didelę riziką duomenų vientisumui.
Suprasdami pg_wal architektūrą, griežtai vengdami destruktyvių archive_command konfigūracijų, stebėdami pg_stat_archiver ir pasitelkdami įmonių lygio atsarginių kopijų platformas, tokias kaip „CloudSave“, galite sukurti atsparią „PostgreSQL“ infrastruktūrą, gebančią išgyventi techninės įrangos gedimus, žmogiškąsias klaidas ir katastrofiškus sutrikimus neprarandant nė vienos įvykdytos operacijos.
Atraskite dažniausiai pasitaikančias „PostgreSQL“ WAL archyvavimo klaidas, vedančias į duomenų praradimą. Sužinokite ekspertų DBA geriausias praktikas, konfigūravimo patarimus ir kaip užtikrinti patikimą atkūrimą tam tikru laiko momentu (PITR) įmonių duomenų bazėms.