Serverdisk 100 % full (0 byte ledig): Återställer en kraschad databas när rm och apt Underkänd på grund av brist på inoder/utrymme¶
Nödnummer skiljer sig åt mellan olika länder. Den här sidan använder 911, numret för USA och Kanada. Många andra länder använder 112, 999 eller ett annat nummer. Hitta numret för ditt land.
Upptäcker att en Linux-produktionsserver har träffat 100% diskanvändning (0 bytes free) eller 100% inodanvändning (df -i) medan du kör en aktiv PostgreSQL-, MySQL/InnoDB-, MariaDB- eller SQLite-databas är ett av de farligaste fellägena inom systemadministration. Vid noll byte eller noll fria inoder, kaskader krisen snabbt: operativsystemets kärna kan inte längre skapa Unix-domänsockets i /tmp eller /var/run, bash misslyckas med att tabb-komplettera eftersom det inte kan skriva tillfälliga skalpipor, apt eller dnf kan inte köra för att rensa upp paket eftersom pakethanterare kräver tillfälliga låsfiler och din databasmotor kraschar mitt i en Write-Ahead-logg (WAL) checkpoint eller vägrar att stänga av rent eftersom den inte kan tilldela ett enda 4 kilobyte (0,004 megabyte) block för sin .pid eller lås filen. Ännu värre är att panikslagna administratörer ofta kör rm -rf /var/log/*.log på multi-gigabyte loggfiler och titta i fasa som df -h rapporterar fortfarande 100% Use% (0 Avail), eller så raderas de dödligt pg_wal (pg_xlog) eller ib_logfile0 för att frigöra utrymme, permanent korrumperar databasen utöver transaktionsåterställning. Om du av misstag raderade viktiga databasfiler under ett rensningsförsök, sluta omedelbart och byt till oavsiktlig rm -rf eller Shift-Delete skrivskyddad återmontering och inodutskärning; om din underliggande lagringshårdvara ger I/O-fel eller har låst sig mot skrivningar, kontakta SSD och NVMe plötsligt skrivskyddat läge och TRIM inaktiverar räddning eller korrupt återställning av Word, Excel, PDF och databasfil. Om detta avbrott påverkar sjukhusets livsäkerhetssystem, akututskick eller kritiska allmännyttiga tjänster, ring ditt lokala nödnummer (911 i USA och Kanada, 112 över hela Europeiska unionen, 999 i Storbritannien) eller konsultera vår globala katalog över nödnummer.
Gör det här nu¶
- Radera INTE
pg_wal/,pg_xlog/,pg_multixact/,ib_logfile*,undo_*, eller-wal/-shmfiler för att skapa utrymme: Att radera Write-Ahead Log eller InnoDB gör om/ångra loggfiler medan en databas kraschar eller är okontrollerad förstör den enda posten av oengagerade sidor och sidor under flygning. En databas med en full disk är 100 procent återvinningsbar när utrymme är frigjort; en databas vars WAL-filer raderades manuellt medrmkommer att drabbas av irreversibel B-träd och hög korruption. - ** Diagnostisera på 5 sekunder om du har slut på diskblock (
df -h), utanför filsystemets inoder (df -i), eller håller öppna olänkade filer (lsof +L1)**: - Kör
df -hför att kontrollera blockkapacitet ochdf -iför att kontrollera inodens kapacitet. En server med 50 gigabyte (53,6 miljarder byte) ledigt diskutrymme kommer fortfarande att kastaNo space left on device (ENOSPC)omdf -ivisarIUse% = 100%(orsakas vanligtvis av miljontals små sessions-, cache- eller e-postspoolfiler). - Om
df -hvisar100%används (0 Avail) även efter att du sprungitrmpå stora loggfiler, körsudo lsof +L1. Alla filer raderade medrmmedannginx,rsyslog,docker,postgres, ellermysqldhar fortfarande en öppen filbeskrivning fortsätter att konsumera 100 procent av dess diskblock tills processen startar om eller du trunkerar deskriptorn direkt. - Frigöra gigabyte utrymme på 1 sekund utan att starta om demoner genom att trunkera öppna filer på plats (
: > /path/to/logfileeller: > /proc/<pid>/fd/<n>): - Istället för
rm /var/log/syslog(vilket lämnar block låsta av den körande loggern), nollställ filen på plats med hjälp av skal-null-omdirigeringen:sudo sh -c ': > /var/log/syslog'ellersudo truncate -s 0 /var/log/syslog. - Om du redan sprungit
rmpå en massiv loggfil ochdf -hsläppte inte, hitta dess process-ID (PID) och filbeskrivning (FD) insudo lsof +L1och trunkera det rakt genom kärnans procfs-gränssnitt:sudo sh -c ': > /proc/<PID>/fd/<FD>'. Space kommer att återvända tilldf -homedelbart. - Lås upp omedelbart andningsrum för nödläge
ext4/ext3genom att sänka den reserverade rotblocksprocenten (tune2fs -m 1): Som standard,ext4reserverar 5 procent av hela partitionen (25 gigabytespå en500 gigabytedisk) exklusivt förUID 0(root), vilket betyder icke-roottjänster sompostgres(UID 109),mysql, ochwww-dataträffaNo space left on devicevid 95 procents utnyttjande. Ta tillbaka 80 procent av denna reserv online på 1 sekund utan stilleståndstid genom att körasudo tune2fs -m 1 /dev/sda1(eller din rotblockeringsenhet frånfindmnt /). - ** Vakuum
systemd-journaldbinära loggar och gamla paketcacher säkert**: Körsudo journalctl --vacuum-size=50M(som säkert roterar och rensar binärt/var/log/journalarkiv ner till 50 megabyte) ochsudo apt-get clean(ellersudo dnf clean all), som tar bort nedladdade.deb/.rpmarkiverar i/var/cache/apt/archives/utan att behöva skriva till dpkg-databasen. - När minst 1 gigabyte till 5 gigabyte (1,07 miljarder till 5,36 miljarder byte) utrymme är ledigt, ta upp databasen i enanvändar- eller återställningsläge för att slutföra sin WAL-kontrollpunkt innan klienttrafik tillåts: Låt PostgreSQL, MySQL/InnoDB eller SQLite spela upp sin Write-Ahead-logg igen (
WAL), spola smutsiga sidor till huvuddatafilerna och återvinn dess uppsvällda WAL-segment rent innan du öppnar din programbrandvägg eller webbserver igen.
Danger
** Spring aldrig pg_resetwal (eller pg_resetxlog) på PostgreSQL eller innodb_force_recovery = 6 på MySQL helt enkelt för att disken fylldes upp**: Körs pg_resetwal torkar transaktionsloggpekarna och tvingar PostgreSQL att börja med halvskrivna datasidor, vilket garanterar tyst radförlust, dubbletter av primärnycklar och trasiga B-träd med främmande nyckel. I 99,9 procent av diskfulla databaskrascher, helt enkelt frigöring av 2 gigabyte till 10 gigabyte (2,1 miljarder till 10,7 miljarder byte) utrymme på partitionen och start av databasdemonen tillåter normalt automatisk kraschåterställning (REDO fas) för att avsluta rent med noll dataförlust.
Beslutsträd: nollutrymmesserver och kraschad databastriage¶
Använd detta beslutsträd för att identifiera varför operativsystemet rapporterar ENOSPC (No space left on device) och välj den exakta oförstörande återställningsvägen:
flowchart TD
Start["Server- eller databaskastning: Inget utrymme kvar på enheten (ENOSPC)"] --> CheckDF["Kör: df -h OCH df -i"]
CheckDF --> DiagType{"Vad rapporterar df?"}
DiagType -->|"df -h visar 100 % användning (0 tillgänglighet) OCH df -i < 95 %"| BlockFull["Block Exhaustion: Kontrollera om du -shx / Matchar df -h"]
DiagType -->|"df -h visar gratis GBs MEN df -i visar 100 % IUse"| InodeFull["Inodutmattning: Miljontals små 0-till-4KB-filer"]
DiagType -->|"Både df -h och df -i Visa < 90 % använd"| RamOrQuota["Dold gräns: Kontrollera df -h /tmp (tmpfs RAM fullt), Docker Overlay2 eller XFS/ext4 diskkvoter"]
BlockFull --> GhostCheck{"Körde du redan rm på stora filer utan att df släpper?"}
GhostCheck -->|"Ja: du är mycket mindre än df"| UnlinkedFD["Kör: sudo lsof +L1 -> Truncate Ghost File via: > /proc/PID/fd/FD"]
GhostCheck -->|"Nej: riktiga filer fylls på disken"| EmergencySpace["Skapa omedelbart andningsrum (1 GB till 5 GB)"]
EmergencySpace --> Ext4Check{"Är filsystemet ext4 / ext3?"}
Ext4Check -->|"Ja"| Tune2fs["Kör: sudo tune2fs -m 1 /dev/root_dev (frigör omedelbart 4 % av disken för icke-root-DB-användare)"]
Ext4Check -->|"Nej (XFS / Btrfs / ZFS)"| TruncLogs["Trunkera loggar på plats (: > /var/log/syslog) och kör journalctl --vacuum-size=50M"]
InodeFull --> InodeClean["Hitta katalog med miljontals filer med find / -xdev -printf '%h\n' | sortera | uniq -c | sortera -k 1 -r | huvud -20 -> Ta bort med hitta -radera"]
UnlinkedFD --> DBRecover["Fortsätt till Database Engine WAL & B-Tree Recovery"]
Tune2fs --> DBRecover
TruncLogs --> DBRecover
InodeClean --> DBRecover
RamOrQuota --> DBRecover
DBRecover --> WhichDB{"Vilken databasmotor kraschade?"}
WhichDB -->|"PostgreSQL"| PGFlow["Håll pg_wal intakt -> Starta Postgres för att spela om WAL -> Kör CHECKPOINT; -> Släpp inaktuella replikeringsplatser"]
WhichDB -->|"MySQL / MariaDB (InnoDB)"| MyFlow["Behåll ib_logfile* Intakt -> Starta mysqld -> Rensa binära loggar via PURGE BINARY LOGS -> Optimera tabeller"]
WhichDB -->|"SQLite3"| SqFlow["Säkerhetskopiera .db + .db-wal + .db-shm -> Kör PRAGMA wal_checkpoint(TRUNCATE) eller sqlite3 broken.db '.recover'"]
Fas 1: Varför standardkommandon (rm, apt, tab-completion) misslyckas vid 0 byte gratis¶
När en Linux-partition når 100 procent block- eller inodutmattning, misslyckas vanliga korrigeringskommandon på oväntade sätt:
- Tryckande Tab in bash kastar cannot create temp file for here-document: No space left on device: Modernt bash-completion skript skapar temporära filer i /tmp. Om /tmp ligger på roten / partition istället för en tmpfs RAM-fäste, skalkomplettering och heredocs (<<EOF) misslyckas. Fixa detta omedelbart genom att peka TMPDIR till delat minne RAM:
apt-get autoremove eller dpkg --configure -a misslyckas med No space left on device: När /boot eller / är 100 procent full, apt kan inte ta bort gamla kärnor pga dpkg måste först skriva statusuppdateringar i /var/lib/dpkg/updates/. Spring istället sudo apt-get clean (som tar bort länkar cachad .deb arkiverar i /var/cache/apt/archives/ direkt), eller trunkera en oanvänd kärnbild i /boot (sudo sh -c ': > /boot/initrd.img-<old-unused-version>') att ge dpkg de 50 megabyte (52,4 miljoner byte) som den behöver för att köras sudo dpkg --purge linux-image-<old-unused-version>.
- rm /path/to/dir/* misslyckas med Argument list too long: När df -i är på 100 procent eftersom en katalog som /var/lib/php/sessions innehåller miljontals små filer, jokertecken globbing (*) svämmar över kärnan ARG_MAX buffert (2 megabytes) innan rm startar. Använd find med -delete istället:
De 5 distinkta orsakerna till No space left on device (ENOSPC)¶
Innan du rör några databasfiler, jämför dessa fem scenarier för att bekräfta vilken resurs som faktiskt är uttömd:
| Diagnostiskt kommando | Symtom observerat | Rotorsak | Omedelbar 10-sekunders fix |
|---|---|---|---|
df -h vs sudo du -shx / |
df -h visar 100% används (0 Avail), men du -shx / läggs till endast 60% av diskstorleken. |
Öppna olänkade filer ("Ghost Files"): Någon sprang rm på en enorm logg eller temporär fil under en process (nginx, java, postgres, docker) hade den fortfarande öppen. |
Kör sudo lsof +L1, lokalisera PID och FD av (deleted) fil och kör sudo sh -c ': > /proc/<PID>/fd/<FD>'. |
df -h visar 95% används, 0 Avail |
Used + Avail är inte lika Size; root kan skriva filer, men postgres eller mysql får ENOSPC. |
ext4 Reserverade rotblock (5 % standard): ext4 undanhåller 5 procent av blockeringarna från icke-rootanvändare (UID > 0) för att förhindra rotlåsning och fragmentering. |
Kör sudo tune2fs -m 1 /dev/<partition> att sänka reserven från 5 procent till 1 procent direkt online. |
df -i |
df -h visar gigabyte ledigt utrymme, men df -i visar IUse% = 100% (IFree = 0). |
Inodutmattning: ext4 har ett fast antal inoder skapade vid mkfs tid; miljontals små filer konsumerade varje inodplats. |
Hitta den skyldige mappen (sudo find / -xdev -printf '%h\n' \ | sortera \ | uniq -c \ | sortera -k 1 -r \ | huvud -10) and run sudo hitta /culprit/dir -typ f -delete. |
sudo mount \ | grep /sökväg |
du -sh /var/log är liten, ändå / har 40 gigabyte saknat utrymme. |
Gömda filer under en monteringspunkt: En process skrev in 40 gigabyte /mnt/backup medan den externa enheten var avmonterad, och senare monterade någon en disk ovanpå /mnt/backup, döljer de underliggande filerna från du. |
Bind-montera rotfilsystemet till en tillfällig vy (sudo mkdir /dev/shm/rootview && sudo mount --bind / /dev/shm/rootview), kontrollera du -sh /dev/shm/rootview/mnt/*och radera de dolda filerna. |
btrfs filesystem df / |
df -h visar 20 gigabyte gratis på en Btrfs volym, men skriver misslyckas med ENOSPC. |
Btrfs Metadata Chunk Exhaustion: Btrfs fördelar utrymme i separata data- och metadatabitar; om allt oallokerat råutrymme är låst till glesa databitar, träffar Metadata-bitar 100 procent. |
Lägg tillfälligt till en 2 gigabyte RAM-filloopenhet (dd if=/dev/zero of=/dev/shm/btrfs_ram bs=1M count=2048 && sudo btrfs device add -f /dev/shm/btrfs_ram /), springa sudo btrfs balance start -dusage=10 /, då sudo btrfs device remove /dev/shm/btrfs_ram /. |
Fas 2: Återta diskutrymme säkert på under 60 sekunder¶
Följ dessa exakta steg för att återta mellan 500 megabyte och 50 gigabyte (0,53 miljarder till 53,6 miljarder byte) utrymme utan att korrumpera aktiva processer:
Steg 1: Trunkera öppna raderade ("spöke") filer via /proc/<pid>/fd/¶
Om du eller ett automatiserat logrotate-skript redan har tagit bort stora filer men diskutrymme inte har returnerats, kontrollera kärnans olänkade öppna filtabell:
Titta påSIZE/OFF kolumn (mätt i byte). Om du ser en post som:
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)
rsyslogd (PID 612, filbeskrivning 7w -> 7) håller en 18,2 gigabyte raderad loggfil öppen. Gör inte det kill -9 databasprocesser (mysqld eller postgres) för att frigöra /tmp filer om du kan frigöra utrymme någon annanstans först. Nollställ istället loggfilsbeskrivningen (PID 612, FD 7) direkt i kärnminnet:
Kör df -h omedelbart: alla 18,2 gigabyte frigörs på plats utan att starta om en enda tjänst.
Steg 2: Återta ext4 reserverade block online med tune2fs¶
På vilken som helst ext4 eller ext3 filsystem, kontrollera det aktuella antalet reserverade block:
postgres), MySQL (mysql), Redis (redis), och SQLite webbappar (www-data, node) körs som oprivilegierade icke-rootanvändare, blockerar Linux-kärnan dem från att använda de sista 5 procenten av disken. Sänka det reserverade blockförhållandet från 5% till 1% (eller 0% under en aktiv nödsituation) träder i kraft omedelbart på ett livemonterat filsystem:
På en 1 terabyte (1 000 gigabyte) databasvolym lämnar detta enda kommando omedelbart 40 gigabyte (42,9 miljarder byte) skrivbart utrymme till din databasmotor så att den kan avsluta sin WAL-kontrollpunkt. När krisen är löst och gammal data rensats, återställ reserven till 2% eller 5% (sudo tune2fs -m 2 /dev/nvme0n1p1).
Steg 3: Trunkera aktiva textloggar på plats och dammsug journald¶
Hitta de största filerna i rotfilsystemet (förblir på samma filsystem som -xdev så att du inte slösar tid på att skanna /proc eller externa fästen):
/var/log/nginx/access.log, /var/log/syslog, /var/log/postgresql/*.log, hamnarbetare *-json.log):
Spring aldrig rm på en aktiv loggfil. Trunkera den till noll byte på plats så att demonens filbeskrivning förblir giltig och offsetpekare återställs rent:
sudo truncate -s 0 /var/log/nginx/error.log
sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
systemd-journald binära loggar (/var/log/journal/):
Fas 3: Återställer PostgreSQL efter en 100% diskfull krasch (pg_wal uppblåsthet)¶
När en PostgreSQL-server får slut på diskutrymme loggas den PANIC: could not write to file "pg_wal/xlogtemp.1234": No space left on device, avbryter omedelbart postmästarens barnprocesser och vägrar starta.
Varför pg_wal (pg_xlog i PostgreSQL 9.6 och äldre) fyller hela disken¶
I normal drift skriver PostgreSQL varje ändring till 16 megabyte (16,7 miljoner byte) segmentfiler inuti $PGDATA/pg_wal/ och återvinner dem efter varje CHECKPOINT en gång överskrider max_wal_size. Det är dock förbjudet för PostgreSQL ** att radera eller återvinna gamla pg_wal filer** under tre villkor:
1. En föräldralös eller eftersläpande fysisk/logisk replikeringsplats: En replikserver (standby), Debezium/Kafka-kontakt, eller pg_receivewal klient kopplades bort för några dagar sedan, men dess replikeringsplats (pg_replication_slots) är stilla active = false på den primära, instruerar PostgreSQL att behålla varje enskilt WAL-segment som genererats sedan frånkopplingen.
2. Ett misslyckande archive_command: archive_mode = on är aktiverat i postgresql.conf, och säkerhetskopieringsskriptet (pgBackRest, WAL-G, Barman, eller aws s3 cp) returnerar en utgångskod som inte är noll (till exempel en utgången S3-nyckel eller oåtkomlig backup-värd). PostgreSQL håller alla oarkiverade WAL-segment inne pg_wal/ tills archive_command returnerar 0.
3. Ett diskfullt dödläge: pg_wal växte fram till 0 bytes stannade kvar /var/lib/postgresql, och nu kan PostgreSQL inte ens börja tappa replikeringsplatsen eller slutföra en kontrollpunkt eftersom startåterställning i sig behöver flera megabyte ledigt diskutrymme för att skriva temporära tillståndsfiler.
Steg-för-steg PostgreSQL nollutrymmesräddning (noll dataförlust)¶
- Skapa 1 gigabyte till 5 gigabyte (1,07 miljarder till 5,36 miljarder byte) tillfälligt utrymme utanför
pg_wal/: - Första användning
sudo tune2fs -m 0 /dev/<partition>och trunkera system/PostgreSQL-textloggar (sudo truncate -s 0 /var/lib/postgresql/*/main/log/*.logeller/var/log/postgresql/*.log). - Tänk om databasen har en egen dedikerad partition med noll textloggar och XFS (så
tune2fsär inte tillgänglig)? Flytta 10 till 20 av de äldsta.readyeller inaktiva filer från en icke-WAL-katalog, eller flyttapg_walkatalog tillfälligt till en annan partition med ledigt utrymme med hjälp av en symbolisk länk:# 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 - Om
archive_commandmisslyckas och blockerar WAL-återvinning, förbigå den tillfälligtpostgresql.conf: Om ditt S3/backup-mål är nere ochpg_wal/archive_status/innehåller tusentals.readyfiler, redigerapostgresql.conf(archive_command = '/bin/true') endast som en sista utväg för att förhindra att skivan dör, med vetskap om att du måste ta en nypg_basebackupomedelbart efter återhämtning eftersom WAL-arkivkedjan kommer att ha en lucka. - Starta PostgreSQL och inspektera omedelbart replikeringsplatser:
Starta PostgreSQL (
sudo systemctl start postgresql) och anslut viasudo -u postgres psql: - Släpp alla döda/inaktiva replikeringsplatser som lagrar gigabyte WAL:
Om du ser en inaktiv plats (
active = f) rymmer 80 gigabyteretained_wal: - Tvinga fram en omedelbar
CHECKPOINTatt återvinna det uppsvälldapg_walsegment: ÖgonblicketCHECKPOINT;avslutas efter att den döda platsen har tappats, kommer PostgreSQL automatiskt att ta bort länken eller återvinna gigabyte av gamla 16 megabyte segmentfiler ipg_wal/, återställer din diskanvändning till det normala. - Förhindra framtida replikeringsplatsdiskdöd: Ställ in
max_slot_wal_keep_sizeinpostgresql.conf(tillgänglig i PostgreSQL 13+) till ett säkert lock (som t.exmax_slot_wal_keep_size = 20GB) så PostgreSQL ogiltigförklarar en död replikas plats istället för att krascha den primära databasen med 0 byte ledig.
Fas 4: Återställa MySQL / MariaDB (InnoDB) vid 0 byte ledig¶
När MySQL eller MariaDB träffar 100% diskanvändning (/var/lib/mysql), InnoDB stoppar alla skrivningar eller kraschar med [ERROR] [MY-012640] [InnoDB] Error number 28 means 'No space left on device'.
Identifiera vad som fyllde /var/lib/mysql¶
Kör sudo du -sh /var/lib/mysql/* | sort -hr | head -n 15 för att se vilka av dessa fyra skyldiga som konsumerade skivan:
1. Obundna binära loggar (binlog.000001, mysql-bin.000042): Som standard i MySQL 8.0+ är binär loggning aktiverad med en 30-dagars retention (binlog_expire_logs_seconds = 2592000), som enkelt kan generera hundratals gigabyte radhändelser under massimporter.
2. En skenande fråga som skriver gigantiska tillfälliga tabeller (#sql* eller ibtmp1): En massiv GROUP BY eller ORDER BY fråga fylld ibtmp1 eller /tmp/#sql_* tills disken träffade 0 byte.
3. ** Monolitisk ibdata1 system tablespace bloat**: Om innodb_file_per_table inaktiverades eller långvariga transaktioner förhindrade InnoDB-historiklistan (ångra loggar inuti ibdata1 eller undo_001) från rensning.
4. MySQL långsam frågelogg eller fellogg (/var/log/mysql/mysql-slow.log).
Steg-för-steg MySQL / MariaDB noll-utrymme räddning¶
- Radera ALDRIG
ibdata1,ib_logfile0,ib_logfile1,#innodb_redo/*, ellerundo_001medrm: Om du tar bort någon av dessa filer blir varje.ibdtabellfilen i din databas oläsbar. - Fritt utrymme för första start (500 megabyte till 2 gigabyte):
- Trunkera
/var/log/mysql/error.logochmysql-slow.logviasudo truncate -s 0 /var/log/mysql/*.log. - På
ext4, springasudo tune2fs -m 1 /dev/<partition>. - Om
mysqldär för närvarande stoppad och/var/lib/mysql/ibtmp1(den icke-komprimerade temporära tabellytan) är enorm,ibtmp1återskapas automatiskt vid start, eller så kan du flytta de äldsta två eller tre binära loggarna (binlog.000001,binlog.000002- aldrig den högst numrerade aktiva binloggen) till/dev/shmtillfälligt såmysqldkan starta. - Starta MySQL och rensa binära loggar säkert med SQL (
PURGE BINARY LOGS): Varför måste du använda SQL istället förrm /var/lib/mysql/binlog.*? Eftersom MySQL spårar alla binära loggfilnamn ibinlog.index. Om du tar bort binära loggar medrmutan uppdateringbinlog.index, kommer MySQL att vägra starta eller replikeringen kommer att gå sönder. En gångmysqldstartar, logga in (sudo mysql) och kör: (Eller rensa allt upp till den aktuella aktiva loggfilen som visas längst ned iSHOW BINARY LOGS;använderPURGE BINARY LOGS TO 'binlog.000085';) - Sätt in en permanent binär loggstorlek och kvarhållningslock
/etc/mysql/mysql.conf.d/mysqld.cnf:Övertäckning[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:5Gibtmp1klmax:5Gsäkerställer att en skurk oindexerasJOINellerORDER BYfråga misslyckas med entable is fullfel istället för att expanderaibtmp1tills hela Linux-servern dör vid 0 byte ledig.
Fas 5: Återställa en skadad SQLite3-databas (database or disk is full / SQLITE_FULL / malformed)¶
Inbäddade applikationer, Docker-behållare (Nextcloud, Vaultwarden, Home Assistant, Plex, Grafana, Gitea), och mobila/datortjänster förlitar sig på SQLite3. När en disk når 0 byte ledig medan SQLite är mitt i en journalåterställning eller en Write-Ahead-logg (-wal) checkpoint kommer du att stöta på en av två nödsituationer:
1. Massiv .db-wal file bloat (den .db-wal filen har vuxit till 10 gigabyte medan .db filen är bara 200 megabyte, eftersom långvariga läsare förhindrade en passiv WAL-kontrollpunkt, och nu är disken 100 procent full).
2. RuntimeError: database disk image is malformed (SQLITE_CORRUPT) orsakad av en trasig hårdvara fsync(), en behållare dödad mitt i rollback med 0 byte ledig, eller någon som tar bort -wal eller -journal fil för hand.
Warning
Flytta aldrig, byt namn på eller kopiera aldrig en .db fil själv medan du lämnar den .db-wal (Write-Ahead Log) eller .db-journal (Rollback Journal) fil bakom: If app.db-wal eller app.db-journal finns vid sidan av app.db, den följefilen innehåller genomförda transaktioner och ursprungliga B-trädsidor som krävs för att göra app.db strukturellt konsekvent. Kopiera alltid alla tre filerna (app.db, app.db-wal, app.db-shm) tillsammans innan du kör något kommando.
Steg 1: Krympa en uppsvälld .db-wal fil och dammsuger SQLite när diskutrymmet är nära noll¶
- Stoppa applikationsbehållaren eller tjänsten som håller SQLite-databasen öppen (
sudo systemctl stop appellerdocker stop container_name). - Kopiera
app.db,app.db-wal, ochapp.db-shmtill en partition eller extern enhet med gott om ledigt utrymme (eller ledigt 2x storleken påapp.dbpå den lokala disken först). - Öppna databasen med
sqlite3CLI och tvinga fram en trunkerande WAL-kontrollpunkt, som viker alla engagerade ramar frånapp.db-walin iapp.dboch krymperapp.db-waltill 0 byte: - Verifiera B-trädets och frilistans strukturella integritet:
Om det skrivs ut
ok, är din databas 100 procent frisk. - ** Hur man
VACUUMen enorm SQLite-databas när den lokala disken inte har tillräckligt med ledigt utrymme**: StandardVACUUM;kräver upp till 2x databasstorleken i ledigt diskutrymme på samma partition och/var/tmp. Använd iställetVACUUM INTO(introducerat i SQLite 3.27.0) för att skriva en nykomprimerad, defragmenterad kopia direkt till en separat monterad disk eller nätverksresurs:
Steg 2: Rädda ett skadat B-träd (database disk image is malformed) med .recover¶
Om PRAGMA integrity_check; rapporterar row 412 missing from index, btreeInitPage() returns error code 11, eller database disk image is malformed:
- Försök först att bygga om trasiga sekundära index (
REINDEX): Ofta de faktiska tabelldata (table B-trees) är 100 procent intakt och endast ett sekundärt index B-träd skadades när disken fylldes. Kör:Omsqlite3 /mnt/external_usb/copy_of_app.db "REINDEX;" sqlite3 /mnt/external_usb/copy_of_app.db "PRAGMA integrity_check;"PRAGMA integrity_check;återkommer nuok, har du återställt 100 procent av din databas med noll förlorade rader. - Om
REINDEXmisslyckas, kör den rättsmedicinska B-tree scanner (.recover): Till skillnad från den äldre.dumpkommando (som slutar exportera en tabell i samma ögonblick som den träffar en skadad B-trädpekare),.recover(inbyggdsqlite3version 3.29.0+) förbigår de skadade inre B-trädpekarna helt, skannar varje obearbetad 4 kilobyte bladsida i filen sekventiellt från byte 0 till EOF, rekonstruerar varje läsbar rad och placerar alla föräldralösa poster i enlost_and_foundtabell: - Verifiera den nyrekonstruerade databasen:
Kontrollera om a
lost_and_foundtabellen skapades (sqlite3 /mnt/external_usb/repaired_app.db ".tables") för att inspektera eventuella föräldralösa rader som återställts från olänkade bladsidor. För krypterade SQLCipher-databaser (som Signal- eller WhatsApp-säkerhetskopior), se vår dedikerade guide om krypterad SQLite, Signal och WhatsApp chat backup korruption och lokal nyckelextraktion.
Fas 6: Nödsituation "Tripwire Ballast File" & checklista för förebyggande av övervakning¶
När din server och databas är online igen, implementera dessa fyra skyddsåtgärder omedelbart så att du aldrig är fången på 0 byte ledig igen:
- Skapa en 1 gigabyte (
1,073,741,824byte) Emergency Ballast File på varje databaspartition: Körsudo fallocate -l 1G /var/lib/EMERGENCY_DELETE_ME.ballast. Om servern någonsin träffar100%disken full, igångsudo rm /var/lib/EMERGENCY_DELETE_ME.ballastfrigör 1 gigabyte av sammanhängande block på 1 millisekund. - Cap
systemd-journaldoch Docker-containerloggar permanent: Ställ inSystemMaxUse=200Min/etc/systemd/journald.confoch konfigurera/etc/docker/daemon.jsonmed"log-opts": {"max-size": "20m", "max-file": "3"}. - Isolera
/var/log,/tmp, och/var/lib/postgresqlpå separata LVM-volymer: Behåller/var/logoch/tmpseparat från databasvolymer säkerställer att en skenande webblogg aldrig kraschar databasen eller låser ute SSH-inloggningar. - Varning på BÅDA
df -h(> 80%) OCHdf -i(> 80%) pluspg_replication_slotsfördröjning: Konfigurera övervakning (node_filesystem_avail_bytesochnode_filesystem_files_free) för att varna innan användningen passerar 85 procent.
Regionala nödnummer och byråprotokoll¶
Medan en full serverdisk normalt är en intern IT-driftsnödsituation, påverkar ett avbrott sjukvårdens elektroniska hälsojournal (EHR) databaser, nödsändning (CAD), kommunal vatten-/krafttelemetri eller lagstadgad tillgång till personuppgifter kan kräva en formell nödupptrappning:
- USA och Kanada: Slå
911om en serverkrasch inaktiverar klinisk övervakning eller sändning och aktiverar driftstopp. Rapportera resursutmattning av kritisk infrastruktur eller ransomware-attacker till CISA (1-844-Say-CISA/cisa.gov/report) eller Canadian Center for Cyber Security (1-833-CYBER-88). - Storbritannien: Ring
999för hot mot liv eller kritiska NHS-system. Under brittiska GDPR och NIS-förordningar, bedöm om permanent databastillgänglighetsförlust kräver meddelande till ICO (0303 123 1113) inom 72 timmar. - Europeiska unionen: Ring
112i alla EU:s medlemsländer. Viktiga enheter enligt NIS2-direktivet måste meddela sin nationella CSIRT inom 24 timmar om ett betydande avbrott, och permanent förlust av personuppgifter utan säkerhetskopiering utlöser rapportering enligt GDPR Artikel 33 inom 72 timmar. - Australien och Nya Zeeland: Ring
000i Australien eller111i Nya Zeeland; kontakta ACSC (1300 CYBER1) för infrastrukturincidenter. - Indien och Asien-Stillahavsområdet: Ring
112för nödsituationer; rapportera cyberinducerade avbrott till CERT-In (incident@cert-in.org.in) inom det obligatoriska 6-timmarsfönstret.
Vanliga frågor¶
Varför gjorde det df -h stanna på 100 % (0 Avail) även efter att jag tagit bort en 50 GB loggfil med rm?¶
I Linux-filsystem, rm bara samtal ta bort länk (), tar bort filnamnet från katalogen medan kärnan behåller diskblocken tilldelade tills varje process som håller den filen öppen stänger dess filbeskrivning (i_count == 0). Kör sudo lsof +L1 för att hitta process-ID (PID) och filbeskrivning (FD) av (raderad) fil och kör sedan sudo sh -c ': > /proc/PID/fd/FD' att nollställa blocken på plats omedelbart utan att starta om tjänsten.
Tänk om jag inte ens kan SSH till servern pga /tmp eller /var/run är 100% full och sshd vägrar att tilldela en session?¶
Försök först att köra ett icke-PTY direkt kommando över SSH utan att allokera en interaktiv pseudoterminal: ssh -T root@server "sh -c ': > /var/log/syslog'". Om rot inloggning är inaktiverad, använd din molnleverantörs out-of-band seriella konsol (AWS EC2 Serial Console, DigitalOcean Console, Linode Lish eller Proxmox/VMware VNC) för att logga in direkt på ttyS0 eller starta i återställningsläge för en användare.
Någon har redan tagit bort filer i PostgreSQL:s pg_wal katalog innan du läser den här guiden, och nu vägrar PostgreSQL att börja med PANIC: could not locate a valid checkpoint record. Går all data förlorad?¶
Nej, de flesta tabellraderna är fortfarande inne $PGDATA/bas/, även om transaktioner ombord i de raderade WAL-filerna går förlorade och vissa sidor kan slitas sönder. Gör först en fullständig kopia av hela $PGDATA katalog (cp -a /var/lib/postgresql/16/main /mnt/backup/pgdata_raw). Spring sedan sudo -u postgres /usr/lib/postgresql/16/bin/pg_resetwal -f /var/lib/postgresql/16/main, starta PostgreSQL i enanvändarläge och kör omedelbart pg_dumpall till en nyinitierad (initdb) kluster; fortsätt aldrig att köra produktionstrafik på ett kluster efteråt pg_resetwal.
Hur tar jag bort miljontals små filer när rm -rf hänger eller går sönder på en inod som är utmattad (df -i 100%) server?¶
När en katalog innehåller miljontals små sessions- eller cachefiler, kommer dess katalogindex (htree) växer enormt, orsakar ls och rm -rf för att stoppa sortering av filnamn i RAM. Spring istället sudo hitta /sökväg/till/million_filer -mindepth 1 -radera, eller skapa en tom RAM-katalog (mkdir /dev/shm/empty) och kör sudo rsync -a --radera /dev/shm/empty/ /path/to/million_files/ för att snabbt koppla bort inoder.
Varför fyllde Docker upp hela min serverdisk när mina containrar i sig är små, och hur rengör jag /var/lib/docker säkert?¶
Docker ackumulerar diskutrymme i oroterade JSON standardloggar (/var/lib/docker/containers/*/*-json.log), dinglande överlägg 2 bildlager och buildkit-cache. Aldrig manuellt rm -rf mappar inuti /var/lib/docker/overlay2/. Först trunkera JSON-loggarna (sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log) så demonen har andrum, kör sedan sudo docker system prune -a -f (utelämnar --volymer så databasvolymer förblir orörda).
Kan jag utöka en moln EBS / persistent diskvolym live medan servern har 100 % diskutnyttjande?¶
Ja, onlinevolymexpansion fungerar utan omstart, med en hake: hjälparskriptet growpart /dev/nvme0n1 1 försöker skapa en temporär fil i /tmp använder mktemp och misslyckas med 0 byte gratis. Förbi det misslyckandet genom att springa sudo TMPDIR=/dev/shm growpart /dev/nvme0n1 1 (med det RAM-stödda /dev/shm montera) följt av sudo resize2fs /dev/nvme0n1p1 (ext4) eller sudo xfs_growfs / (XFS).
Relaterade guider¶
- Oavsiktlig
rm -rfellerShift+Deletepå Linux, macOS eller Windows: omedelbar skrivskyddad återmontering - Krypterad SQLite, Signal och WhatsApp chat backup korruption och lokal nyckelextraktion
- Skadade Word-, Excel-, PDF- och databasfiler och osparade dokumentåterställning
- SSD och NVMe plötsligt skrivskyddat läge, 0 % reservblock och TRIM-inaktiverande räddning
- Kris för webbhotell, migrering och återställning av säkerhetskopiering
- Nödnummer per land
Källor och officiell vägledning¶
- PostgreSQL Global Development Group: Officiell dokumentation för PostgreSQL 16 - Kapitel 30: Tillförlitlighet och Write-Ahead-loggen (WAL-konfiguration, replikeringsplatser och återställning från diskfulla fel).
- SQLite Consortium (
sqlite.org): Hur man korrumperar en SQLite-databasfil (fillåsning, olänkade journal-/WAL-filer och.recoverCLI-tillägg). - Oracle Corporation / MySQL Documentation & MariaDB Foundation: InnoDB Crash Recovery, Binary Log Purge Procedures (
PURGE BINARY LOGS), och Temporary Tablespace (ibtmp1) Ledning. - Linux Kernel Organisation (
kernel.org): Ext4 filsystemadministration (tune2fsReserverade block, inodtabeller och/proc/<pid>/fd/File Descriptor Trunkering). - National Institute of Standards and Technology (
NIST) (USA): Specialpublikation 800-123: Guide to General Server Security and Availability Management.