Es kommt vor, dass die Festplatte laut „df -h“ voll (oder fast voll) ist, die mit dem Befehl „du“ addierten Verzeichnisgrößen jedoch deutlich weniger anzeigen und nicht feststellbar ist, was den fehlenden Speicherplatz einnimmt. Die Verwendung dieser beiden Befehle wird im Artikel „Wie lässt sich die Festplattennutzung auf einem Linux-Server überprüfen (Befehle ‚du‘ und ‚df‘)?“ behandelt. Für diese Abweichung gibt es einige typische Ursachen; es lohnt sich, diese der Reihe nach durchzugehen.
1. Gelöschte, aber noch geöffnete Dateien
Der häufigste Grund: Eine große Datei (in der Regel eine Protokolldatei) wurde gelöscht, wird jedoch noch von einem laufenden Programm (Webserver, Datenbank, PHP-Prozess) offen gehalten. Unter Linux wird der Inhalt der Datei in diesem Fall erst freigegeben, wenn das Programm sie schließt: Die Datei ist im Verzeichnis nicht mehr sichtbar, sodass sie vom Befehl „du“ nicht mehr gezählt wird, laut „df“ belegt sie jedoch weiterhin Speicherplatz.
Die Liste der gelöschten, aber noch offenen Dateien auf einem bestimmten Dateisystem (hier im Stammverzeichnis):
sudo lsof -a +L1 /
+L1 wählt bereits gelöschte (verknüpfungslose) Dateien aus, / wählt das Stammverzeichnis aus, und -a legt fest, dass beide Bedingungen erfüllt sein müssen. Ohne das -a-Argument werden die beiden Bedingungen durch „oder“ verknüpft, und lsof listet alle geöffneten Dateien im Stammverzeichnis auf. Der einfache Befehl sudo lsof +L1 funktioniert ebenfalls, hat jedoch im Test auch die im Systemspeicher gehaltenen Dateien (/memfd:…) ausgegeben, die keinen Speicherplatz auf der Festplatte belegen.
oder, falls „lsof“ nicht installiert ist (sudo dnf install lsof / sudo apt install lsof):
sudo find /proc/*/fd -ls 2>/dev/null | grep '(deleted)'
Auf einem Testrechner mit AlmaLinux 10 haben wir eine 600 MB große „error_log“-Datei von Apache gelöscht, während der Dienst lief. Laut „df“ hat sich der belegte Speicherplatz nicht verringert (er blieb bei 2,0 GB), laut „du“ war das Protokollverzeichnis leer, und „lsof“ zeigte an, wer die Datei noch offen hält:
Die Spalte „COMMAND“ zeigt das Programm an, „SIZE/OFF“ die Dateigröße in Byte (hier 629.146.459 Byte, d. h. 600 MB). Dieselbe Datei wird sowohl vom Hauptprozess des Webservers (root) als auch von dessen Arbeitsprozessen (apache) geöffnet gehalten. Um Speicherplatz freizugeben, starten Sie den betreffenden Dienst neu:
sudo systemctl restart httpd
Falls sich der Dienst nicht neu starten lässt, kann der Inhalt der Datei auch über den Dateideskriptor des Prozesses geleert werden. Anhand der Nummern in den Spalten „PID“ und „FD“ (ohne Buchstaben, im obigen Bild 2848 und 2):
sudo truncate -s 0 /proc/2848/fd/2
Im Test wurden dadurch sofort 600 MB freigegeben (der Wert von „df“ sank von 2,0 GB auf 1005 MB), und nach dem Neustart des Dienstes verschwand die gelöschte Datei auch aus der „lsof“-Liste. Wenn mehrere Prozesse dieselbe Datei geöffnet haben, reicht es aus, sie über einen davon zu leeren, da es sich um dieselbe Datei handelt.
Wie können Sie dies beim nächsten Mal vermeiden?
Löschen Sie eine aktuell verwendete Protokolldatei nicht (mit dem Befehl „rm“), sondern leeren Sie sie:
sudo truncate -s 0 /var/log/httpd/error_log
Auf diese Weise kann das Programm weiterlaufen, und der Speicherplatz wird sofort freigegeben. Zum Thema „Suche nach großen Protokolldateien“: So finden und entfernen Sie große error_log-Dateien unter Linux.
2. Die Inodes sind aufgebraucht
Sollte trotz der Fehlermeldung „No space left on device“ laut df -h noch freier Speicherplatz vorhanden sein, hat möglicherweise die Anzahl der Dateien auf dem Dateisystem das Limit erreicht. Dies wird durch den Schalter -i angezeigt:
df -i
Bei einem Test auf einem kleinen ext4-Dateisystem brach der Befehl „touch“ nach Erschöpfung der Inodes mit folgender Meldung ab: „touch: cannot touch '/mnt/kis/f94': No space left on device“, obwohl laut „df -h“ noch 88 MB frei waren und laut „df -i“ der IUse%-Wert bei 100 % lag.
Wenn der Wert in der Spalte „IUse%“ nahe bei 100 % liegt, befinden sich sehr viele kleine Dateien auf der Festplatte, typischerweise Sitzungsdateien (sessions), Cache-Dateien oder nicht zugestellte E-Mails. In welchem Verzeichnis sich die meisten Dateien befinden:
sudo du --inodes -x / 2>/dev/null | sort -n | tail -n 20
Informationen zum Begriff „Inode“ finden Sie im Artikel „Was bedeutet ein Inode?“.
3. Der für das Root-Verzeichnis reservierte Speicherplatz (ext4)
Das ext4-Dateisystem reserviert standardmäßig 5 % des Speicherplatzes für den Root-Benutzer, damit das System auch dann funktionsfähig bleibt, wenn die Benutzer die Festplatte vollständig belegt haben. Aus diesem Grund ist die Summe aus „Used“ und „Avail“ gemäß „df“ kleiner als der Wert von „Size“, und ein normaler Benutzer sieht die Festplatte bereits als „voll“ an, während der Root-Benutzer noch darauf schreiben kann.
Auf einer Datenfestplatte (nicht auf der Systemfestplatte) lässt sich der reservierte Speicherplatz reduzieren, beispielsweise auf 1 %:
sudo tune2fs -m 1 /dev/vdb1
Der aktuelle Wert wird durch den Befehl „sudo tune2fs -l /dev/vdb1 | grep -i 'reserved block count'“ angezeigt; im Test waren von den 102.400 Blöcken eines frisch formatierten ext4-Dateisystems 5.120 (5 %) reserviert, nach Ausführung von „tune2fs -m 1“ waren es 1.024.
Das XFS-Dateisystem (Standard unter AlmaLinux und Rocky Linux) reserviert keinen solchen Speicherplatz.
4. Dateien, die unter einem Mountpunkt verborgen sind
Wenn Sie ein weiteres Laufwerk an ein Verzeichnis (z. B. /mnt/data oder /home) angehängt haben, werden die zuvor in diesem Verzeichnis vorhandenen Dateien vom angehängten Laufwerk überlagert: Der Befehl „du“ erkennt sie nicht mehr, doch sie belegen weiterhin Speicherplatz auf der Systemfestplatte. Dies tritt typischerweise dann auf, wenn das zweite Laufwerk nach einem Neustart nicht wieder eingebunden wurde und Programme in der Zwischenzeit Daten auf die Systemfestplatte geschrieben haben.
Die ausgeblendeten Dateien können eingesehen werden, indem Sie das Stammverzeichnis an einem anderen Speicherort einbinden:
sudo mkdir /mnt/rootfs
sudo mount --bind / /mnt/rootfs
sudo du -sh /mnt/rootfs/mnt/data
Im Test haben wir eine 50-MB-Datei in das Verzeichnis „/mnt/data“ geschrieben, bevor wir dort eine weitere Festplatte gemountet haben: Der Befehl „du -sh /mnt/data“ zeigte 15 KB an, der Befehl „du -sh /mnt/rootfs/mnt/data“ hingegen 50 MB. Sollten Sie hier Daten vorfinden, verschieben Sie diese bitte auf die gemountete Festplatte und heben Sie anschließend die Verbindung auf:
sudo umount /mnt/rootfs
5. Sonstige Gründe
- Das systemd-Protokoll: Es kann mit dem Befehl „
journalctl --disk-usage“ überprüft und mit dem Befehl „journalctl --vacuum-size=500M“ verkleinert werden (siehe: Protokoll-Dateien unter Linux lesen). - Alte Kernel und der Cache des Paketmanagers: „
sudo dnf clean all“ oder „sudo apt clean“ und „sudo apt autoremove“. - Docker: Nicht verwendete Images und Container im Verzeichnis „
/var/lib/docker“ können viel Speicherplatz beanspruchen; der Befehl „docker system df“ zeigt den Speicherplatzverbrauch an, der Befehl „docker system prune“ bereinigt den Speicherplatz. - Datenbank-binlogs: Die Replikationsprotokolle (
binlogs) von MariaDB/MySQL können unbegrenzt anwachsen, wenn keine Verfallszeit festgelegt ist.
Sollte der Speicherplatz dauerhaft knapp werden, kann die Festplatte erweitert werden (siehe: „Wie kann ich die Ressourcen meines VPS-Pakets erweitern?“ und „Wie kann ich das Dateisystem nach der Erweiterung der VPS-Festplatte vergrößern?“).
