Felhasználói eszközök

Eszközök a webhelyen


it:postgres_user_group:cikkek:nincs_hely_az_archivalashoz

Nincs hely az archiváláshoz! Mit tegyek?

Ha a PostgreSQL adatbázisunkat szeretnénk online menteni, és adott esetben a múlt egy bizonyos pontján létező állapotra helyreállítani (point-in-time recovery), akkor archívmódban kell használnunk az adatbázis-szervert. Az archívmód azt jelenti, hogy a megtelt WAL-fájlokat a szerver archiválja, mielőtt törli vagy újra felhasználja őket.

Ha a PostgreSQL nem tud archiválni egy WAL-fájlt, akkor újrapróbálja addig, amíg nem sikerül. Ha egyszer vagy kétszer nem sikerül az archiválás, akkor a következőt írja a szervernaplóba:

LOG: archive command failed with exit code … Harmadjára már ezt írja:

WARNING: archiving write-ahead log file „…” failed too many times, will try again later

A archiválás több okból is meghiúsulhat. A leggyakoribb az, hogy nincs hely kiírni az új archív WAL-fájlt.

Archívlogok mentése és törlése

A helybetelés gyakran abból fakad, hogy az archívált WAL-fájlok – más néven archívlogok – ott maradnak az archívterületen, azokat nem pucolja ki senki és semmi. Az archívlogok törlése azok mentésével kapcsolatban szokott általában megtörténni, ám erről a DBA-nak kell valamiképpen gondoskodnia.

Az archívlogok félig automatikus törlésére használható a pg_archivecleanup parancssoros eszköz. Ez az eszköz arra képes, hogy a legutóbbi mentést megelőzően keletkezett archívlogokat törölje, amennyiben a mentés a PostgreSQL eszközkészletével történt. A pg_archivecleanup a parancsot lehet futtatni kézzel, ütemezetten, vagy a mentési megoldás részeként. További részletek a hivatalos dokumentációban, angolul: https://www.postgresql.org/docs/current/pgarchivecleanup.html

Betöltéskor keletkező archívlogok

A helybetelés másik gyakori oka az, hogy a szokottnál több WAL-fájl keletkezik, amit archiválni kell, amivel az archívlog-terület méretezésekor nem terveztünk. Ez például tipikusan betöltések során fordul elő.

Ha lehet tudni, hogy mikor és milyen hosszan van redo-intenzív terhelés – például betöltés –, ami miatt sok WAL keletkezik, akkor ez alapján is lehet nagyobbra méretezni az archívlog-területet.

Ha az adatbetöltés során nem tudunk elbánni a keletkezett WAL-mennyiséggel, akkor akár az archivmód ideiglenes kikapcsolása is jelenthet megoldást. A kikapcsoláshoz elegendő az archive_command szerverparaméter értékét törölni, üres karaktersorozatra beállítani (archive_command=). Ilyenkor ugyan figyelmeztetéseket ír a naplóba a szerver, hogy az archívmód be van kapcsolva, de az archiválást végző parancs nincs beállítva, cserébe viszont ezt a módosítást a szerver újraindítása nélkül is meg lehet tenni.

A betöltés után vissza kell kapcsolni az archívmódot, és egy teljes mentést kell készíteni az adatbázisró. Ellenkező esetben veszélyeztetjük betöltött adatok, illetve akár későbbi módosítások helyreállíthatóságát is. Néhány további tippet találunk a betöltések gyorsítására a hivatalos dokumentációban, angolul: https://www.postgresql.org/docs/current/populate.html

WAL-terület és archívlog-terület kapcsolata

Sikertelen archiválás esetén törölni sem tudja azokat a WAL-fájlokat a szerver, amiket archiválni szeretne. Ha ez a helyzet huzamosabb ideig áll fent, akkor ez előbb-utóbb oda vezet, hogy betelik a WAL-fájlok számára fenntartott lemezterület is.

Ha a WAL-terület betelik, akkor a PostgreSQL azonnal megáll, mivel a WAL-fájlok tartalma a PostgreSQL működésének kritikusan fontos része, anélkül nem biztosítható ugyanis az adatkonzisztencia.

A PostgreSQL-ben van egy logikai felső korlát a WAL-fájlok összméretére: a max_wal_size paraméter. Ez a korlát viszont nem szigorú korlát. Például éppen a sikertelen archiválás estén túllépheti ezt a szerver.

Ha tehát az archiválás valamiért nem működik, például mert betelt az archívlog-terület, akkor a max_wal_size paraméterben beállított méretet bármennyivel túl tudja lépni a szerver.

WAL-terület méretezése

A WAL-terület méretezésére sajnos nincs egyszerű recept, alapvetően empirikus úton lehet eljutni a megfelelő értékekhez.

Az adatbázisok mérete sem mindig segít, ugyanis ezzel sem feltétlenül arányos a keletkező WAL mennyisége. Utóbbi ugyanis a redo-intenzív műveletek (tipikusan DML-műveletek) számától függ. Ez nagy adatbázisok esetén is lehet csekély, ha alapvetően csak olvassuk az adatbázist, és kisebb adatbázisok esetén is lehet számottevő, ha azt intenzíven módosítjuk.

Ökölszabályként érdemes kétszer annyi lemezterület fenntartani a WAL-fájlok számára, mint amekkora a max_wal_size paraméter értéke. Ez a tartalék hely az időlegesen megnövekedett WAL-mennyiség esetére jelenthet áthidaló megoldás, de csupán abban az esetben, ha az archiválás egyébként működik, csak éppen nem tud lépést tartani a WAL-fájlok keletkezésének ütemével.

WAL-terület betelése

Ha a WAL-terület betelése miatt a szerver megáll, akkor a következő szerverindítás során automatikus helyreállítás (crash recovery) történik. Ha a WAL-terület még mindig tele van, akkor ez a helyreállítás is meghiúsul, a szervert nem lehet elindítani.

Indítás előtt valahogy helyet kell még biztosítani a WAL-terleten. Ezt több módon is meg lehet tenni.

A legszebb és legkényelmesebb megoldás az, ha a WAL-fájlok külön köteten vannak, és ennek a kötetnek a méretét meg lehet növelni.

Ha nem tudjuk a méretét megnövelni, de van egy másik kötet, ahol van hely, akkor a WAL-fájlokat át lehet másolni erre a kötetre, és a pg_wal könyvtárat (ahol a WAL-fájlok vannak) szimbolikus linkké lehet tenni, ami az új helyre mutat.

Ha a fentiek nem lehetségesek, akkor egy régi klasszikus trükk, az, hogy egy pl. 200 MB-os fájlt már előre létrehoznak a WAL-területen, mondjuk NE_TOROLD_LE_CSAK_VESZ_ESETEN néven, és ha betelik WAL-terület, akkor a DBA ezt a fájlt törli az újraindítás előtt. Így le tud futni a helyreállítás indulásokor, és el tud indulni az adatbázis-szerver.

A sikeres szerverindítás után érdemes kézzel egy checkpointot kikényszeríteni, a CHECKPOINT utasítás kiadásával.

Záró gondolatok

Ha betelik az archívlogok alatt a lemez, az a gyakran a szerver megállását fogja eredményezni. Ennek elkerülése érdekében rendszeresen érdemes rendszeresen menteni az adatbázist és az archívlogokat is. Az a legjobb, ha a mentőmegoldás egyúttal az archívlogok törlését is automatikusan intézi.

Mindenképpen érdemes monitorozni a WAL-területet és az archívlog-területet telítettségét, hogy helycsökkenés esetén proaktívan be lehessen avatkozni.

it/postgres_user_group/cikkek/nincs_hely_az_archivalashoz.txt · Utolsó módosítás: 2023/07/30 21:29 szerkesztette: rblst