Skip to content

Kiszolgálólemez 100%-ban megtelt (0 bájt ingyenes): Összeomlott adatbázis helyreállítása, amikor rm és apt Fail Inodes/Space hiánya miatt

A segélyhívó számok országonként eltérőek. Ez az oldal a 911-et használja, amely az Egyesült Államokra és Kanadára vonatkozik. Sok más országban a 112-es, 999-es vagy más számokat használják. Keresse meg az országának megfelelő számot.

Felfedeztük, hogy egy éles Linux-szerver elütött 100% lemezhasználat (0 bytes free) vagy 100% inode kihasználtság (df -i) aktív PostgreSQL, MySQL/InnoDB, MariaDB vagy SQLite adatbázis futtatása közben az egyik legveszélyesebb hibamód a rendszeradminisztrációban. Nulla bájt vagy nulla szabad inode esetén a válság gyorsan kaszkádolódik: az operációs rendszer kernelje már nem tud Unix tartományi socketeket létrehozni /tmp vagy /var/run, bash nem tudja a tabulátort befejezni, mert nem tud ideiglenes shell-csöveket írni, apt vagy dnf nem fut a csomagok megtisztítására, mert a csomagkezelőknek ideiglenes zárolási fájlokra van szükségük, és az adatbázismotor összeomlik az előreírási napló közepén (WAL). .pid vagy zárolja a fájlt. Még rosszabb, hogy a pánikba esett rendszergazdák gyakran futnak rm -rf /var/log/*.log több gigabájtos naplófájlokon, és nézd meg rémülten, mint df -h továbbra is tudósít 100% Use% (0 Avail), vagy végzetesen törlik pg_wal (pg_xlog) vagy ib_logfile0 helyet szabadítson fel, a tranzakció-helyreállításon túlmenően véglegesen megsértve az adatbázist. Ha véletlenül törölte a kritikus adatbázisfájlokat a tisztítási kísérlet során, azonnal állítsa le, és váltson a következőre véletlen rm -rf vagy Shift-Delete csak olvasható újracsatlakoztatás és inode carving; Ha az alapul szolgáló tárolóhardver I/O hibákat dob ki, vagy blokkolta magát az írás ellen, forduljon hozzá SSD és NVMe hirtelen csak olvasható mód és a TRIM letiltása vagy sérült Word, Excel, PDF és adatbázis fájlok helyreállítása. Ha ez a kimaradás érinti a kórházi életbiztonsági rendszereket, a segélyszolgálatot vagy a kritikus közműveket, hívja a helyi segélyhívó számot (911 az Egyesült Államokban és Kanadában, 112 az Európai Unió egész területén, 999 az Egyesült Királyságban), vagy tekintse meg globális címtárunkat segélyhívó számok.

Tedd ezt most

  1. ** NE törölje pg_wal/, pg_xlog/, pg_multixact/, ib_logfile*, undo_*, vagy -wal / -shm fájlok, hogy helyet szabadítsanak fel**: Az előreírási napló vagy az InnoDB újraírási/visszavonási naplófájljainak törlése, miközben egy adatbázis összeomlik vagy nincs bejelölve, megsemmisíti a nem véglegesített és folyamatban lévő oldalak egyetlen rekordját. A megtelt lemezzel rendelkező adatbázis 100 százalékban helyreállítható, ha hely szabadul fel; olyan adatbázis, amelynek WAL-fájljait manuálisan törölték rm visszafordíthatatlan B-fa és kupac korrupciót fog szenvedni.
  2. ** 5 másodpercen belül diagnosztizálja, hogy kifogytak-e a lemezblokkok (df -h), a fájlrendszer inode-jain kívül (df -i), vagy tartsa nyitva a nem összekapcsolt fájlokat (lsof +L1)**:
  3. Fuss df -h blokk kapacitásának ellenőrzésére és df -i a bemeneti kapacitás ellenőrzésére. Az 50 gigabájt (53,6 milliárd bájt) szabad lemezterülettel rendelkező szerver továbbra is dob No space left on device (ENOSPC) ha df -i mutatja IUse% = 100% (általában milliónyi apró munkamenet-, gyorsítótár- vagy levélspoolfájl okozza).
  4. Ha df -h mutatja 100% használt (0 Avail) még futás után is rm hatalmas naplófájlokon futtassa sudo lsof +L1. Bármely fájl törölve ezzel rm miközben nginx, rsyslog, docker, postgres, vagy mysqld továbbra is nyitott fájlleírót tart fenn, és a lemezblokkjainak 100 százalékát lefoglalja, amíg a folyamat újra nem indul, vagy közvetlenül nem csonkolja a leírót.
  5. Gigabájt tárhely felszabadítása 1 másodperc alatt a démonok újraindítása nélkül a nyitott fájlok helyükre történő csonkolásával (: > /path/to/logfile vagy : > /proc/<pid>/fd/<n>):
  6. Ahelyett rm /var/log/syslog (ami a blokkokat a futó naplózó által zárolva hagyja), nullázza a fájlt a helyén a shell null átirányítással: sudo sh -c ': > /var/log/syslog' vagy sudo truncate -s 0 /var/log/syslog.
  7. Ha már futott rm egy hatalmas naplófájlon és df -h nem esett le, keresse meg a folyamatazonosítóját (PID) és fájlleíró (FD) be sudo lsof +L1 és vágja le egyenesen a kernel procfs felületén keresztül: sudo sh -c ': > /proc/<PID>/fd/<FD>'. A tér visszatér ide df -h azonnal.
  8. ** Azonnali sürgősségi légzőszoba feloldása ext4 / ext3 a fenntartott gyökérblokk százalékának csökkentésével (tune2fs -m 1)**: Alapértelmezés szerint ext4 fenntartja a teljes partíció 5 százalékát (25 gigabytes a 500 gigabyte lemez) kizárólag a számára UID 0 (root), azaz a nem root szolgáltatások, mint pl postgres (UID 109), mysql, és www-data ütni No space left on device 95 százalékos kihasználtság mellett. A tartalék 80 százalékát online 1 másodperc alatt, nulla leállás nélkül szerezheti vissza sudo tune2fs -m 1 /dev/sda1 (vagy a gyökérblokk eszközödről findmnt /).
  9. Vákuum systemd-journald bináris naplók és régi csomag gyorsítótárak biztonságosan: Futtatás sudo journalctl --vacuum-size=50M (ami biztonságosan forgatja és törli a bináris /var/log/journal archívum 50 megabájtig) és sudo apt-get clean (vagy sudo dnf clean all), amely törli a letöltött fájlokat .deb / .rpm archívumban /var/cache/apt/archives/ anélkül, hogy a dpkg adatbázisba kellene írnia.
  10. Miután legalább 1-5 gigabájt (1,07-5,36 milliárd bájt) szabad terület, hozza létre az adatbázist egyfelhasználós vagy helyreállítási módban, hogy befejezze a WAL-ellenőrzőpontját, mielőtt engedélyezné az ügyfélforgalmat: Hagyja, hogy a PostgreSQL, a MySQL/InnoDB vagy az SQLite újra lejátssza a Write-Ahead naplóját (WAL), öblítse át a piszkos oldalakat a fő adatfájlokba, és tisztán hasznosítsa újra a felduzzadt WAL-szegmenseket, mielőtt újra megnyitná az alkalmazás tűzfalát vagy webszerverét.

Danger

Soha ne fuss pg_resetwal (vagy pg_resetxlog) PostgreSQL-en vagy innodb_force_recovery = 6 a MySQL-en egyszerűen azért, mert megtelt a lemez: Fut pg_resetwal törli a tranzakciós napló mutatóit, és arra kényszeríti a PostgreSQL-t, hogy félig megírt adatlapokkal induljon, garantálva a néma sorvesztést, az elsődleges kulcsok megkettőzését és a törött idegen kulcsú B-fákat. A lemezzel megtelt adatbázis-összeomlások 99,9 százalékánál egyszerűen 2-10 gigabájt (2,1-10,7 milliárd bájt) terület szabadul fel a partíción, és az adatbázis-démon elindítása általában lehetővé teszi az automatikus összeomlás-helyreállítást (REDO fázis), hogy tisztán, adatveszteség nélkül fejezze be.


Döntési fa: nulla helyet foglaló szerver és összeomlott adatbázis-osztályozás

Használja ezt a döntési fát annak meghatározására, hogy miért jelent az operációs rendszer ENOSPC (No space left on device), és válassza ki a pontos, roncsolásmentes helyreállítási utat:

flowchart TD
    Start["Szerver vagy adatbázis dobása: Nincs szabad hely az eszközön (ENOSPC)"] --> CheckDF["Futtatás: df -h ÉS df -i"]

    CheckDF --> DiagType{"Mit jelent a df?"}

    DiagType -->|"df -h 100%-os használatot mutat (0 elérhető) ÉS df -i < 95%"| BlockFull["Kimerülés blokkja: Ellenőrizze, hogy a du -shx / egyezik-e a df -h paraméterrel"]
    DiagType -->|"df -h Megmutatja a szabad GB-okat, DE a df -i 100% IUse-t mutat"| InodeFull["Inode kimerülés: milliónyi apró 0-4 KB méretű fájl"]
    DiagType -->|"A df -h és a df -i is < 90% használt"| RamOrQuota["Rejtett korlát: Ellenőrizze a df -h /tmp (tmpfs RAM megtelt), a Docker Overlay2 vagy az XFS/ext4 lemezkvótákat"]

    BlockFull --> GhostCheck{"Futtatta már az rm-t nagy fájlokon anélkül, hogy a df eldobta volna?"}
    GhostCheck -->|"Igen: du sokkal kisebb, mint a df"| UnlinkedFD["Futtassa: sudo lsof +L1 -> Csonka Ghost fájl a következőn keresztül: > /proc/PID/fd/FD"]
    GhostCheck -->|"Nem: Valódi fájlok töltik ki a lemezt"| EmergencySpace["Azonnali lélegzőhely létrehozása (1 GB és 5 GB között)"]

    EmergencySpace --> Ext4Check{"A fájlrendszer ext4/ext3?"}
    Ext4Check -->|"Igen"| Tune2fs["Futtatás: sudo tune2fs -m 1 /dev/root_dev (Azonnal felszabadítja a lemez 4%-át a nem root DB felhasználók számára)"]
    Ext4Check -->|"Nem (XFS / Btrfs / ZFS)"| TruncLogs["A naplók helyben történő csonkolása (: > /var/log/syslog) és a journalctl futtatása --vacuum-size=50M"]

    InodeFull --> InodeClean["Könyvtár keresése több millió fájllal a find / -xdev -printf '%h\n' | segítségével rendezés | uniq -c | sort -k 1 -r | head -20 -> Delete with find -delete"]

    UnlinkedFD --> DBRecover["Folytassa a WAL és B-Tree Recovery adatbázismotorral"]
    Tune2fs --> DBRecover
    TruncLogs --> DBRecover
    InodeClean --> DBRecover
    RamOrQuota --> DBRecover

    DBRecover --> WhichDB{"Melyik adatbázismotor omlott össze?"}
    WhichDB -->|"PostgreSQL"| PGFlow["A pg_wal sértetlen megőrzése -> Postgres indítása a WAL újrajátszásához -> CHECKPOINT futtatása; -> Drop Stale Replication Slots"]
    WhichDB -->|"MySQL / MariaDB (InnoDB)"| MyFlow["Az ib_logfile* sértetlen megőrzése -> Mysqld indítása -> Bináris naplók törlése a BINÁRIS NAPLÓK TÖRLÉSE segítségével -> Táblázatok optimalizálása"]
    WhichDB -->|"SQLite3"| SqFlow["Biztonsági mentés .db + .db-wal + .db-shm -> Futtassa a PRAGMA wal_checkpoint(TRUNCATE) vagy sqlite3 broken.db '.recover' parancsot"]

1. fázis: Miért szabványos parancsok (rm, apt, tab-completion) sikertelen 0 bájtnál

Amikor egy Linux-partíció eléri a 100 százalékos blokkolást vagy az inode-kimerülést, a szabványos javítási parancsok váratlan módon meghiúsulnak: - ** Nyomja meg Tab be bash dobások cannot create temp file for here-document: No space left on device**: Modern bash-completion A szkriptek ideiglenes fájlokat hoznak létre /tmp. Ha /tmp a gyökéren lakik / partíció a helyett tmpfs RAM mount, shell kiegészítés és heredocs (<<EOF) sikertelen. Rögzítse ezt azonnal rámutatással TMPDIR megosztott memória RAM:

export TMPDIR=/dev/shm
- apt-get autoremove vagy dpkg --configure -a nem sikerül No space left on device: Mikor /boot vagy / 100 százalékig megtelt, apt nem távolíthatja el a régi kernelt, mert dpkg először be kell írnia az állapotfrissítéseket /var/lib/dpkg/updates/. Inkább fuss sudo apt-get clean (ami leválasztja a gyorsítótárat .deb archívumban /var/cache/apt/archives/ közvetlenül), vagy csonkoljon le egy nem használt kernelképet /boot (sudo sh -c ': > /boot/initrd.img-<old-unused-version>') adni dpkg a futtatásához szükséges 50 megabájt (52,4 millió bájt). sudo dpkg --purge linux-image-<old-unused-version>. - rm /path/to/dir/* nem sikerül Argument list too long: Mikor df -i 100 százalékon van, mert tetszik egy könyvtár /var/lib/php/sessions milliónyi apró fájlt tartalmaz, helyettesítő karakterekkel (*) túlcsordul a rendszermagon ARG_MAX puffer (2 megabytes) előtt rm elindul. Használja find -val -delete helyette:
sudo find /var/lib/php/sessions -type f -delete

Az 5 különböző oka No space left on device (ENOSPC)

Mielőtt hozzányúlna az adatbázisfájlokhoz, hasonlítsa össze az alábbi öt forgatókönyvet, hogy megbizonyosodjon arról, hogy valójában melyik erőforrás merült ki:

Diagnosztikai parancs Tünet megfigyelhető Kiváltó ok Azonnali 10 másodperces javítás
df -h vs sudo du -shx / df -h mutatja 100% használt (0 Avail), de du -shx / csak annyit tesz ki 60% a lemez méretétől. Nyissa meg a nem összekapcsolt fájlokat ("Ghost Files"): Valaki futott rm egy hatalmas napló- vagy ideiglenes fájlon folyamat közben (nginx, java, postgres, docker) még nyitva volt. Fuss sudo lsof +L1, keresse meg a PID és FD a (deleted) fájlt, és futtassa sudo sh -c ': > /proc/<PID>/fd/<FD>'.
df -h műsorok 95% használt, 0 Avail Used + Avail nem egyenlő Size; root tud fájlokat írni, de postgres vagy mysql kap ENOSPC. ext4 Fenntartott gyökérblokkok (5%-os alapértelmezés): ext4 visszatartja a blokkolások 5 százalékát a nem root felhasználóktól (UID > 0) a gyökérzárak és a töredezettség elkerülése érdekében. Fuss sudo tune2fs -m 1 /dev/<partition> hogy a tartalékot 5 százalékról azonnal 1 százalékra csökkentsék online.
df -i df -h gigabájt szabad területet mutat, de df -i mutatja IUse% = 100% (IFree = 0). Inode kimerülés: ext4 fix számú inode-ja van létrehozva a címen mkfs idő; milliónyi apró fájl fogyasztott el minden inode slotot. Keresse meg a bűnös mappát (sudo find / -xdev -printf '%h\n' \ | rendezés \ | egyedi -c \ | rendezés -k 1 -r \ | fej -10) and run sudo find /bűnös/könyvtár -type f -delete.
sudo mount \ | grep /útvonal du -sh /var/log még kicsi / 40 gigabájtnyi hely hiányzik. Rejtett fájlok csatlakozási pont alatt: Egy folyamat 40 gigabájtot írt bele /mnt/backup míg a külső meghajtót leválasztották, és később valaki egy lemezt tetejére szerelt /mnt/backup, elrejti a mögöttes fájlokat du. A gyökér fájlrendszer összekapcsolása egy ideiglenes nézethez (sudo mkdir /dev/shm/rootview && sudo mount --bind / /dev/shm/rootview), ellenőrizze du -sh /dev/shm/rootview/mnt/*, és törölje a rejtett fájlokat.
btrfs filesystem df / df -h 20 gigabájtot mutat szabadon a Btrfs kötet, mégis meghiúsul az írás ENOSPC. Btrfs Metaadat-darabok kimerülése: Btrfs külön adat- és metaadat-darabokra foglal helyet; ha az összes fel nem osztott nyers terület ritka adatdarabokba van zárva, a metaadat-darabok elérik a 100 százalékot. Ideiglenesen adjon hozzá egy 2 gigabájtos RAM fájlhurok eszközt (dd if=/dev/zero of=/dev/shm/btrfs_ram bs=1M count=2048 && sudo btrfs device add -f /dev/shm/btrfs_ram /), fuss sudo btrfs balance start -dusage=10 /, akkor sudo btrfs device remove /dev/shm/btrfs_ram /.

2. fázis: A lemezterület biztonságos visszanyerése 60 másodperc alatt

Kövesse az alábbi lépéseket, hogy 500 és 50 gigabájt (0,53-53,6 milliárd bájt) területet nyerjen vissza az aktív folyamatok megsértése nélkül:

1. lépés: Csonkítsa le a megnyitott törölt ("szellem") fájlokat a következőn keresztül /proc/<pid>/fd/

Ha Ön vagy egy automatikus logrotate szkript már törölt nagy fájlokat, de a lemezterület nem került vissza, ellenőrizze a kernel nem csatolt nyitott fájltáblázatát:

sudo lsof +L1
Nézd meg a SIZE/OFF oszlop (bájtban mérve). Ha ilyen bejegyzést lát:
COMMAND    PID     USER   FD   TYPE DEVICE    SIZE/OFF NLINK    NODE NAME
mysqld    1942    mysql    6u   REG  259,1 34896609280     0  918273 /tmp/ibXz91aB (deleted)
rsyslogd   612   syslog    7w   REG  259,1 18253611008     0  131092 /var/log/syslog.1 (deleted)
itt, rsyslogd (PID 612, fájlleíró 7w -> 7) egy 18,2 gigabájtos törölt naplófájlt tart nyitva. Nem kill -9 adatbázis folyamatok (mysqld vagy postgres) ingyenes /tmp fájlokat, ha előbb máshol tud helyet felszabadítani. Ehelyett nullázza le a naplófájl leíróját (PID 612, FD 7) közvetlenül a kernel memóriájában:
sudo sh -c ': > /proc/612/fd/7'
Fuss df -h azonnal: mind a 18,2 gigabájt a helyszínen felszabadul, egyetlen szolgáltatás újraindítása nélkül.

2. lépés: Visszakövetelés ext4 lefoglalt blokkok online tune2fs

Bármelyiken ext4 vagy ext3 fájlrendszer, ellenőrizze az aktuális lefoglalt blokkok számát:

df -h /
sudo tune2fs -l /dev/nvme0n1p1 | grep -i "reserved block"
Mivel a PostgreSQL (postgres), MySQL (mysql), Redis (redis), és SQLite webalkalmazások (www-data, node) jogosulatlan, nem root felhasználóként fut, a Linux kernel megakadályozza, hogy a lemez utolsó 5 százalékát használják. A lefoglalt blokk arányának csökkentése innen 5% hogy 1% (vagy 0% aktív vészhelyzet során) azonnal érvénybe lép egy élőben csatolt fájlrendszeren:
sudo tune2fs -m 1 /dev/nvme0n1p1
Egy 1 terabájtos (1000 gigabájtos) adatbázisköteten ez az egyetlen parancs azonnal 40 gigabájt (42,9 milliárd bájt) írható területet ad át az adatbázis-motornak, hogy az befejezhesse a WAL-ellenőrzési pontot. A válság megoldása és a régi adatok törlése után állítsa vissza a tartalékot 2% vagy 5% (sudo tune2fs -m 2 /dev/nvme0n1p1).

3. lépés: Az aktív szövegnaplók csonkolása és porszívózása journald

Keresse meg a legnagyobb fájlokat a gyökér fájlrendszeren (a fájlrendszeren maradva a -xdev így nem vesztegeti az időt a szkenneléssel /proc vagy külső rögzítők):

sudo find / -xdev -type f -size +100M -exec ls -lh {} + 2>/dev/null | sort -k 5 -hr | head -n 25
- Nagy egyszerű szöveges naplófájlokhoz (/var/log/nginx/access.log, /var/log/syslog, /var/log/postgresql/*.log, Docker *-json.log): Soha ne fuss rm egy aktív naplófájlban. Csonkítsa le nulla bájtra, hogy a démon fájlleírója érvényes maradjon, és az eltolási mutatók tisztán visszaálljanak:
sudo truncate -s 0 /var/log/nginx/error.log
sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
- ** Mert systemd-journald bináris naplók (/var/log/journal/)**:
sudo journalctl --vacuum-size=50M


3. fázis: A PostgreSQL helyreállítása 100%-ban megtelt lemez összeomlás után (pg_wal puffadás)

Amikor egy PostgreSQL-kiszolgáló kifogy a lemezterületből, naplóz PANIC: could not write to file "pg_wal/xlogtemp.1234": No space left on device, azonnal megszakítja a postmaster gyermek folyamatokat, és nem hajlandó elindítani.

Miért pg_wal (pg_xlog PostgreSQL 9.6 és régebbi verziókban) kitölti a teljes lemezt

Normál működés esetén a PostgreSQL minden változást 16 megabájtos (16,7 millió bájtos) szegmensfájlokba ír $PGDATA/pg_wal/ és mindegyik után újrahasznosítja őket CHECKPOINT ha egyszer meghaladja max_wal_size. A PostgreSQL ** azonban tilos a régiek törlése vagy újrahasznosítása pg_wal fájlok** három feltétel mellett: 1. Egy árva vagy késésben lévő fizikai/logikai replikációs hely: replikaszerver (standby), Debezium/Kafka csatlakozó, ill pg_receivewal az ügyfél néhány nappal ezelőtt megszakadt, de a replikációs nyílása (pg_replication_slots) még mindig active = false az elsődlegesen, utasítva a PostgreSQL-t, hogy őrizzen meg minden egyes WAL-szegmenst, amely a leválasztás óta keletkezett. 2. Egy kudarc archive_command: archive_mode = on be van kapcsolva postgresql.conf, és a biztonsági mentési szkript (pgBackRest, WAL-G, Barman, vagy aws s3 cp) nullától eltérő kilépési kódot ad vissza (például lejárt S3 kulcsot vagy elérhetetlen biztonsági mentési gazdagépet). A PostgreSQL minden archiválatlan WAL-szegmenst bent tart pg_wal/ amíg archive_command visszatér 0. 3. A lemez megtelt holtpont: pg_wal ig nőtt 0 bytes rajta maradt /var/lib/postgresql, és most a PostgreSQL még csak nem is kezdheti el a replikációs nyílás eldobását vagy egy ellenőrzési pontot, mert az indítási helyreállításnak magának több megabájt szabad lemezterületre van szüksége az ideiglenes állapotfájlok írásához.

Lépésről lépésre a PostgreSQL nulla térbeli mentése (nulla adatvesztés)

  1. Hozzon létre 1-5 gigabájt (1,07-5,36 milliárd bájt) ideiglenes helyet kívül pg_wal/:
  2. Első használat sudo tune2fs -m 0 /dev/<partition> és csonkolja a rendszer/PostgreSQL szövegnaplókat (sudo truncate -s 0 /var/lib/postgresql/*/main/log/*.log vagy /var/log/postgresql/*.log).
  3. Mi van akkor, ha az adatbázis saját dedikált partícióval rendelkezik nulla szövegnaplóval és XFS-sel (tehát tune2fs nem érhető el)? Mozgassa a legrégebbi 10-ét 20-ra .ready vagy inaktív fájlokat nem WAL-könyvtárból, vagy helyezze át a pg_wal könyvtárat ideiglenesen egy másik partícióra, ahol van szabad hely egy szimbolikus hivatkozás segítségével:
    # ONLY while PostgreSQL is completely stopped (verify with: ps aux | grep postgres)
    sudo mkdir -p /mnt/extra_space/pg_wal_rescue
    sudo chown -R postgres:postgres /mnt/extra_space/pg_wal_rescue
    sudo mv /var/lib/postgresql/16/main/pg_wal/* /mnt/extra_space/pg_wal_rescue/
    sudo rmdir /var/lib/postgresql/16/main/pg_wal
    sudo ln -s /mnt/extra_space/pg_wal_rescue /var/lib/postgresql/16/main/pg_wal
    sudo chown -h postgres:postgres /var/lib/postgresql/16/main/pg_wal
    
  4. Ha archive_command meghibásodik, és blokkolja a WAL-újrahasznosítást, ideiglenesen hagyja ki postgresql.conf: Ha az S3/tartalék célpontja leállt és pg_wal/archive_status/ több ezret tartalmaz .ready fájlokat, szerkessze postgresql.conf (archive_command = '/bin/true') csak végső vészhelyzeti intézkedésként a lemez elhalásának megakadályozására, tudván, hogy újat kell venni pg_basebackup azonnal a helyreállítás után, mert a WAL archívum lánc rés lesz.
  5. Indítsa el a PostgreSQL-t, és azonnal ellenőrizze a replikációs helyeket: Indítsa el a PostgreSQL-t (sudo systemctl start postgresql) és ezen keresztül csatlakozni sudo -u postgres psql:
    SELECT slot_name, plugin, slot_type, active,
           pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS retained_wal
    FROM pg_replication_slots;
    
  6. Emeljen le minden halott/inaktív replikációs nyílást, amely gigabájt WAL-t halmoz fel: Ha inaktív helyet lát (active = f) 80 gigabájttal retained_wal:
    SELECT pg_drop_replication_slot('name_of_dead_slot');
    
  7. ** Azonnali kényszerítés CHECKPOINT hogy újrahasznosítsa a dagadt pg_wal szegmensek**:
    CHECKPOINT;
    
    A pillanat CHECKPOINT; a halott slot eldobása után befejeződik, a PostgreSQL automatikusan leválasztja vagy újrahasznosítja a régi 16 megabájtos szegmensfájlok gigabájtjait. pg_wal/, visszaállítja a lemezhasználatot a normál értékre.
  8. A jövőbeni replikációs slot lemezhalál megelőzése: Beállítva max_slot_wal_keep_size be postgresql.conf (elérhető a PostgreSQL 13+-ban) biztonságos korlátra (pl max_slot_wal_keep_size = 20GB), így a PostgreSQL érvényteleníti a halott replika slotját, ahelyett, hogy az elsődleges adatbázist 0 bájton összeomlana.

4. fázis: A MySQL / MariaDB helyreállítása (InnoDB) 0 bájton szabad

Amikor a MySQL vagy a MariaDB eléri 100% lemezhasználat (/var/lib/mysql), az InnoDB leállítja az összes írást vagy összeomlik [ERROR] [MY-012640] [InnoDB] Error number 28 means 'No space left on device'.

Azonosítása, hogy mi töltötte be /var/lib/mysql

Fuss sudo du -sh /var/lib/mysql/* | sort -hr | head -n 15 hogy megtudd, a négy tettes közül ki fogyasztotta el a lemezt: 1. Korlátlan bináris naplók (binlog.000001, mysql-bin.000042): A MySQL 8.0+-ban alapértelmezés szerint a bináris naplózás engedélyezve van 30 napos megőrzéssel (binlog_expire_logs_seconds = 2592000), amely könnyen generálhat több száz gigabájtnyi soreseményt a tömeges importálás során. 2. Egy elszabadult lekérdezés óriási ideiglenes táblákat írva (#sql* vagy ibtmp1): Hatalmas GROUP BY vagy ORDER BY lekérdezés kitöltve ibtmp1 vagy /tmp/#sql_* amíg a lemez el nem éri a 0 bájtot. 3. ** Monolit ibdata1 system tablespace bloat**: Ha innodb_file_per_table le volt tiltva, vagy a régóta futó tranzakciók megakadályozták az InnoDB előzménylistáját (a naplók visszavonása ibdata1 vagy undo_001) a tisztítástól. 4. MySQL lassú lekérdezési napló vagy hibanapló (/var/log/mysql/mysql-slow.log).

Lépésről lépésre MySQL / MariaDB nulla térbeli mentés

  1. ** SOHA ne töröld ibdata1, ib_logfile0, ib_logfile1, #innodb_redo/*, vagy undo_001 -val rm**: Ezen fájlok bármelyikének törlése minden .ibd táblafájl az adatbázisában olvashatatlan.
  2. Ingyenes kezdeti indítási terület (500 megabájt és 2 gigabájt között):
  3. Csonka /var/log/mysql/error.log és mysql-slow.log keresztül sudo truncate -s 0 /var/log/mysql/*.log.
  4. Be ext4, fuss sudo tune2fs -m 1 /dev/<partition>.
  5. Ha mysqld jelenleg le van állítva és /var/lib/mysql/ibtmp1 (a nem tömörített ideiglenes tábla táblaterülete) hatalmas, ibtmp1 indításkor automatikusan újra létrejön, vagy áthelyezheti a legrégebbi két vagy három bináris naplót (binlog.000001, binlog.000002 - soha nem a legmagasabb számú aktív binlog) to /dev/shm átmenetileg így mysqld bootolhat.
  6. Indítsa el a MySQL-t és törölje biztonságosan a bináris naplókat SQL használatával (PURGE BINARY LOGS): Miért kell SQL helyett használni? rm /var/lib/mysql/binlog.*? Mivel a MySQL minden bináris naplófájlnevet nyomon követ binlog.index. Ha törli a bináris naplókat a rm frissítés nélkül binlog.index, a MySQL megtagadja az indulást, vagy a replikáció megszakad. Egyszer mysqld elindul, jelentkezz be (sudo mysql) és futtassa:
    SHOW BINARY LOGS;
    PURGE BINARY LOGS BEFORE NOW() - INTERVAL 1 DAY;
    
    (Vagy töröljön mindent az aktuális aktív naplófájlig, amely az alján látható SHOW BINARY LOGS; segítségével PURGE BINARY LOGS TO 'binlog.000085';)
  7. ** Állítsa be az állandó bináris naplóméretet és a tartósapkát /etc/mysql/mysql.conf.d/mysqld.cnf**:
    [mysqld]
    binlog_expire_logs_seconds = 259200   # Keep only 3 days (259,200 seconds)
    max_binlog_size = 256M
    innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:5G
    
    Kupakolás ibtmp1 at max:5G biztosítja, hogy egy gazember ne legyen indexelve JOIN vagy ORDER BY a lekérdezés sikertelen a table is full hiba bővítés helyett ibtmp1 amíg a teljes Linux-szerver el nem hal 0 byte-on.

5. fázis: Sérült SQLite3 adatbázis helyreállítása (database or disk is full / SQLITE_FULL / malformed)

Beágyazott alkalmazások, Docker konténerek (Nextcloud, Vaultwarden, Home Assistant, Plex, Grafana, Gitea), a mobil/asztali szolgáltatások pedig az SQLite3-ra támaszkodnak. Amikor egy lemez eléri a 0 bájtot, miközben az SQLite egy napló-visszagörgetés vagy egy előreírási napló közepén van (-wal) ellenőrzőpont, két vészhelyzet egyikével találkozhat: 1. ** Masszív .db-wal file bloat** (a .db-wal fájl 10 gigabájtra nőtt, miközben a .db fájl csak 200 megabájt, mert a régóta futó olvasók megakadályozták a passzív WAL-ellenőrzőpontot, és most a lemez 100 százalékban megtelt). 2. RuntimeError: database disk image is malformed (SQLITE_CORRUPT) törött hardver okozta fsync(), a konténer megölte mid-rollback at 0 byte free, vagy valaki törli a -wal vagy -journal kézzel fájlba.

Warning

Soha ne helyezze át, nevezze át vagy másolja át a .db fájl önmagában, miközben elhagyja .db-wal (Előre írási napló) ill .db-journal (Rollback Journal) fájl mögött: Ha app.db-wal vagy app.db-journal mellett létezik app.db, az a kísérőfájl lekötött tranzakciókat és az elkészítéséhez szükséges eredeti B-fa oldalakat tartalmazza app.db szerkezetileg konzisztens. Mindig másolja mind a három fájlt (app.db, app.db-wal, app.db-shm) együtt, mielőtt bármilyen parancsot futtatna.

1. lépés: A dagadt zsugorítása .db-wal fájl és az SQLite felszívása, amikor a lemezterület közel nulla

  1. Állítsa le az SQLite adatbázist nyitva tartó alkalmazástárolót vagy szolgáltatást (sudo systemctl stop app vagy docker stop container_name).
  2. Másolás app.db, app.db-wal, és app.db-shm partícióra vagy külső meghajtóra, ahol sok szabad hely van (vagy 2x akkora app.db először a helyi lemezen).
  3. Nyissa meg az adatbázist a sqlite3 CLI és kényszerít egy csonkolt WAL-ellenőrzőpontot, amely az összes lefoglalt keretet kihajtja app.db-wal be app.db és összezsugorodik app.db-wal 0 bájtig:
    sqlite3 /path/to/app.db "PRAGMA wal_checkpoint(TRUNCATE);"
    
  4. Ellenőrizze a B-fa és a szabadlista szerkezeti integritását:
    sqlite3 /path/to/app.db "PRAGMA integrity_check;"
    
    Ha kinyomtatja ok, az adatbázisa 100 százalékban egészséges.
  5. Hogyan VACUUM egy hatalmas SQLite adatbázis, ha a helyi lemezen nincs elég szabad hely: Szabványos VACUUM; az adatbázis méretének legfeljebb 2-szeresére kell lennie szabad lemezterületen ugyanazon a partíción és /var/tmp. Ehelyett használja VACUUM INTO (az SQLite 3.27.0-ban bevezetve), hogy egy frissen tömörített, töredezettségmentesített másolatot közvetlenül egy különálló lemezre vagy hálózati megosztásra írjon:
    sqlite3 /path/to/app.db "VACUUM INTO '/mnt/external_usb/app_compacted.db';"
    

2. lépés: A sérült B-fa megmentése (database disk image is malformed) -val .recover

Ha PRAGMA integrity_check; jelentéseket row 412 missing from index, btreeInitPage() returns error code 11, vagy database disk image is malformed:

  1. Először próbálja meg újraépíteni a törött másodlagos indexeket (REINDEX): Gyakran a tényleges táblázatadatok (table B-trees) 100 százalékban sértetlen, és csak egy másodlagos index B-fa sérült meg, amikor a lemez megtelt. Futtatás:
    sqlite3 /mnt/external_usb/copy_of_app.db "REINDEX;"
    sqlite3 /mnt/external_usb/copy_of_app.db "PRAGMA integrity_check;"
    
    Ha PRAGMA integrity_check; most visszatér ok, akkor az adatbázis 100 százalékát helyreállította nulla elveszett sor nélkül.
  2. Ha REINDEX sikertelen, futtassa a törvényszéki B-tree szkennert (.recover): Ellentétben a régebbiekkel .dump parancs (amely leállítja a tábla exportálását abban a pillanatban, amikor az egy sérült B-fa mutatót talál), .recover (beépítve sqlite3 3.29.0+ verzió) teljesen megkerüli a sérült belső B-fa mutatóit, a fájl minden nyers 4 kilobyte-os levéloldalát egymás után megvizsgálja a 0. bájttól az EOF-ig, minden olvasható sort rekonstruál, és az árva rekordokat egy lost_and_found táblázat:
    sqlite3 /mnt/external_usb/copy_of_app.db ".recover" | sqlite3 /mnt/external_usb/repaired_app.db
    
  3. Ellenőrizze az újonnan rekonstruált adatbázist:
    sqlite3 /mnt/external_usb/repaired_app.db "PRAGMA integrity_check;"
    
    Ellenőrizze, hogy a lost_and_found táblázat létrehozva (sqlite3 /mnt/external_usb/repaired_app.db ".tables"). A titkosított SQLCipher adatbázisok (például a Signal vagy a WhatsApp biztonsági mentések) tekintetében tekintse meg a külön útmutatónkat titkosított SQLite, Signal és WhatsApp csevegési biztonsági mentések sérülése és helyi kulcs kivonása.

6. fázis: Sürgősségi "Tripwire Ballast File" és megfigyelési megelőzési ellenőrzőlista

Miután a szerver és az adatbázis újra online állapotba került, azonnal hajtsa végre ezt a négy biztosítékot, hogy soha többé ne essen 0 bájt csapdájába:

  • ** Hozzon létre egy 1 gigabájtos (1,073,741,824 bájt) Emergency Ballast File minden adatbázis-partíción**: Futtassa sudo fallocate -l 1G /var/lib/EMERGENCY_DELETE_ME.ballast. Ha a szerver valaha is eltalál 100% lemez megtelt, fut sudo rm /var/lib/EMERGENCY_DELETE_ME.ballast 1 gigabájt szomszédos blokkokat szabadít fel 1 ezredmásodperc alatt.
  • Kap systemd-journald és Docker konténernaplók állandóan: Beállítva SystemMaxUse=200M be /etc/systemd/journald.conf és konfigurálja /etc/docker/daemon.json -val "log-opts": {"max-size": "20m", "max-file": "3"}.
  • ** Elszigetelni /var/log, /tmp, és /var/lib/postgresql külön LVM kötetekre**: Megtartás /var/log és /tmp Az adatbázis-kötetektől elkülönítve biztosítja, hogy az elszabadult webnapló soha ne omolja össze az adatbázist, és ne zárja ki az SSH-bejelentkezéseket.
  • Figyelmeztetés MINDKÉTRE df -h (> 80%) ÉS df -i (> 80%) plusz pg_replication_slots lag: Monitoring konfigurálása (node_filesystem_avail_bytes és node_filesystem_files_free) figyelmeztetni, mielőtt a kihasználtság meghaladja a 85 százalékot.

Regionális segélyhívó számok és ügynökségi protokollok

Míg a teljes szerverlemez általában belső informatikai műveletek vészhelyzete, egy leállás, amely hatással van az egészségügyi elektronikus egészségügyi nyilvántartásra (EHR) adatbázisok, segélyszolgálat (CAD), a települési víz/áram telemetria vagy a személyes adatok kötelező elérhetősége hivatalos vészhelyzeti eszkalációt igényelhet:

  • Egyesült Államok és Kanada: Tárcsázza 911 ha a szerver összeomlása letiltja a klinikai megfigyelést vagy a küldést, és aktiválja a leállási eljárásokat. Jelentse a kritikus infrastruktúra erőforrás-kimerülését vagy a zsarolóprogramok támadásait a CISA-nak (1-844-Say-CISA / cisa.gov/report) vagy a Canadian Center for Cyber Security (1-833-CYBER-88).
  • Egyesült Királyság: Tárcsázza 999 életveszély vagy kritikus NHS-rendszerek esetén. Az Egyesült Királyság GDPR- és NIS-rendeleteinek megfelelően értékelje, hogy az adatbázis-elérhetőség állandó elvesztéséhez szükséges-e az ICO (0303 123 1113) 72 órán belül.
  • Európai Unió: Tárcsázza 112 az EU összes tagállamában. A NIS2-irányelv hatálya alá tartozó alapvető entitásoknak 24 órán belül értesíteniük kell nemzeti CSIRT-jüket egy jelentős kiesésről, és a személyes adatok tartós elvesztése biztonsági mentés helyreállítása nélkül a GDPR 33. cikke szerinti jelentést 72 órán belül kiváltja.
  • Ausztrália és Új-Zéland: Tárcsázza 000 Ausztráliában vagy 111 Új-Zélandon; lépjen kapcsolatba az ACSC-vel (1300 CYBER1) infrastrukturális eseményekre.
  • India és Ázsia-csendes-óceáni térség: Tárcsázza 112 vészhelyzet esetén; jelentse a cyber által kiváltott leállásokat a CERT-In (incident@cert-in.org.in) a kötelező 6 órás időtartamon belül.

Gyakran ismételt kérdések

Miért tette df -h maradj 100%-on (0 Avail) még azután is, hogy töröltem egy 50 GB-os naplófájlt rm?

Linux fájlrendszerekben rm csak hívásokat unlink(), eltávolítja a fájlnevet a könyvtárból, miközben a kernel lefoglalja a lemezblokkokat mindaddig, amíg minden, a fájlt nyitva tartó folyamat be nem zárja a fájlleíróját (i_count == 0). Fuss sudo lsof +L1 hogy megtalálja a folyamatazonosítót (PID) és fájlleíró (FD) a (törölve) fájlt, majd futtassa sudo sh -c ': > /proc/PID/fd/FD' hogy azonnal nullázza a blokkokat a helyükön a szolgáltatás újraindítása nélkül.

Mi van, ha még az SSH-t sem tudom bevinni a szerverre, mert /tmp vagy /var/run 100%-ban megtelt és sshd nem hajlandó kijelölni egy munkamenetet?

Először próbáljon meg végrehajtani egy nem PTY közvetlen parancsot SSH-n keresztül interaktív pszeudoterminál lefoglalása nélkül: ssh -T root@server "sh -c ': > /var/log/syslog'". Ha gyökér A bejelentkezés le van tiltva, használja a felhőszolgáltató sávon kívüli soros konzolját (AWS EC2 Serial Console, DigitalOcean Console, Linode Lish vagy Proxmox/VMware VNC) a közvetlen bejelentkezéshez ttyS0 vagy indítsa el az egyfelhasználós helyreállítási módot.

Valaki már törölt fájlokat a PostgreSQL-ben pg_wal könyvtárat, mielőtt elolvasta ezt az útmutatót, és most a PostgreSQL nem hajlandó kezdeni vele PANIC: could not locate a valid checkpoint record. Minden adat elveszett?

Nem, a legtöbb táblázatsor még bent van $PGDATA/alap/, bár a törölt WAL-fájlokon belüli repülés közbeni tranzakciók elvesznek, és egyes oldalak elszakadhatnak. Először készítsen teljes másolatot az egészről $PGDATA könyvtár (cp -a /var/lib/postgresql/16/main /mnt/backup/pgdata_raw). Aztán fuss sudo -u postgres /usr/lib/postgresql/16/bin/pg_resetwal -f /var/lib/postgresql/16/main, indítsa el a PostgreSQL-t egyfelhasználós módban, és azonnal futtassa pg_dumpall egy frissen inicializált (initdb) klaszter; soha ne futtasson tovább éles forgalmat egy fürtön ezután pg_resetwal.

Hogyan törölhetek milliónyi kis fájlt, amikor rm -rf lefagy vagy meghibásodik egy inode-kimerült (df -i 100%) szerver?

Ha egy könyvtár több millió apró munkamenet- vagy gyorsítótárfájlt tartalmaz, a könyvtárindex (htree) hatalmasra nő, ami ls és rm -rf hogy leállítsa a fájlnevek rendezését a RAM-ban. Inkább fuss sudo keresse meg a /elérési utat/hoz/hoz/millió_fájlhoz -mindepth 1 -delete, vagy hozzon létre egy üres RAM könyvtárat (mkdir /dev/shm/empty) és fuss sudo rsync -a --delete /dev/shm/empty/ /útvonal/hoz/hoz/millió_fájl/ az inódák gyors leválasztásához.

Miért töltötte fel a Docker a teljes szerverlemezemet, amikor maguk a tárolóim kicsik, és hogyan tisztíthatom meg /var/lib/docker biztonságosan?

A Docker lemezterületet halmoz fel el nem forgatott JSON-stdout naplókban (/var/lib/docker/containers/*/*-json.log), csüngő overlay2 képrétegek és buildkit gyorsítótár. Soha ne kézzel rm -rf mappákat belül /var/lib/docker/overlay2/. Először csonkolja le a JSON-naplókat (sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log), így a démonnak van légzési helyisége, majd futtassa sudo docker rendszer aszalt szilva -a -f (kihagyva -- kötetek így az adatbázis-kötetek érintetlenek maradnak).

Bővíthetek egy felhőalapú EBS/persistent lemezkötetet élőben, miközben a szerver 100%-os lemezkihasználtságon van?

Igen, az online kötetbővítés újraindítás nélkül működik, egyetlen fogással: a segédszkripttel növekedési rész /dev/nvme0n1 1 megpróbál létrehozni egy ideiglenes fájlt /tmp segítségével mktemp és 0 bájtnál meghiúsul. Kerülje ki a hibát futással sudo TMPDIR=/dev/shm növekedési rész /dev/nvme0n1 1 (RAM-mal támogatott /dev/shm mount) követi sudo resize2fs /dev/nvme0n1p1 (ext4) vagy sudo xfs_growfs / (XFS).


Kapcsolódó útmutatók


Források és hivatalos útmutatás

  • PostgreSQL globális fejlesztési csoport: PostgreSQL 16 hivatalos dokumentáció - 30. fejezet: Megbízhatóság és az előre írási napló (WAL-konfiguráció, replikációs helyek és helyreállítás a lemez teljes meghibásodása esetén).
  • SQLite konzorcium (sqlite.org): Hogyan ronthatunk el egy SQLite-adatbázisfájlt (fájlzárolás, nem csatolt napló-/WAL-fájlok és .recover CLI kiterjesztés).
  • Oracle Corporation / MySQL Documentation & MariaDB Foundation: InnoDB Crash Recovery, Binary Log Purge Procedures (PURGE BINARY LOGS), és ideiglenes táblaterület (ibtmp1) Menedzsment.
  • A Linux kernel szervezete (kernel.org): Ext4 fájlrendszer adminisztráció (tune2fs Fenntartott blokkok, Inode táblázatok és /proc/<pid>/fd/ Fájlleíró csonkítása).
  • Nemzeti Szabványügyi és Technológiai Intézet (NIST) (Egyesült Államok): Különleges kiadvány 800-123: Útmutató az általános szerverbiztonsághoz és elérhetőség-kezeléshez.