Ausgehender Speicherplatz ist der häufigste Grund, aus dem ein Server ganz ohne böse Absicht stehen bleibt. Die Website liefert 500, die Datenbank schreibt nicht, Mail geht nicht hinaus — und df -h meldet dabei mehrere freie Gigabyte. Gehen wir alle drei Fälle durch, in denen das passiert, und dazu, was man über SMART wissen sollte.

Fall eins: Die Inodes sind aufgebraucht

Ein Dateisystem hält zwei begrenzte Ressourcen vor: Platz für Inhalte und Einträge über Dateien. Die zweite geht unabhängig von der ersten zur Neige:

df -h
df -i

Steht IUse% im zweiten Befehl auf 100, liegt es an den Inodes. Platz ist vorhanden, aber es lässt sich keine einzige Datei mehr anlegen, nicht einmal eine leere.

Die Verursacher sind stets dieselben: Millionen winziger Dateien. PHP-Sitzungen in /var/lib/php/sessions, deren Aufräumen kaputtgegangen ist. Ein Anwendungscache, der nie geleert wird. Eine feststeckende Mail-Warteschlange. Ein Verzeichnis mit Vorschaubildern. Finden lassen sie sich so:

sudo find / -xdev -type f -printf '%h\n' 2>/dev/null | sort | uniq -c | sort -rn | head -20

Der Befehl nennt die Verzeichnisse mit den meisten Dateien. Auf einem großen System läuft er minutenlang — das ist normal.

Fall zwei: Die Datei ist gelöscht, der Platz kam nicht zurück

Die heimtückischere Lage. Jemand hat ein übergroßes Protokoll mit rm entfernt, aber der schreibende Prozess hält es weiterhin offen. Die Datei ist nicht mehr im Verzeichnis, der Platz bleibt belegt, und das bis zum Neustart des Prozesses.

sudo lsof +L1

Der Befehl zeigt Dateien ohne Verweis im Dateisystem, die aber noch von einem Prozess gehalten werden. Die Abhilfe ist ein Neustart oder sanftes Neuladen dieses Prozesses, nicht die Suche nach „wo sind die Gigabyte hin“.

Daraus die Regel: Ein übergroßes Protokoll wird nicht gelöscht, sondern geleert — dann bleibt der offene Dateizeiger brauchbar:

sudo truncate -s 0 /var/log/huge.log

Und gleich danach die Rotation einrichten, sonst wiederholt sich das Ganze binnen einer Woche.

Fall drei: Die Protokolle haben ihn gefressen

Wohin der Platz genau ging, zeigt ein Abstieg Ebene für Ebene:

sudo du -x -h --max-depth=1 / | sort -h
sudo du -x -h --max-depth=1 /var | sort -h

Der Schalter -x verhindert das Abwandern auf andere Dateisysteme; ohne ihn kriecht die Zählung nach /proc und in Netzwerkeinbindungen. Bequemer geht das alles in ncdu, sofern vorhanden.

Die üblichen Verschlinger:

  • journald. Ein Befehl klärt es: journalctl --disk-usage. Begrenzt wird es mit der Zeile SystemMaxUse=500M in /etc/systemd/journald.conf, einmalig bereinigt mit journalctl --vacuum-size=200M;
  • Protokolle von Sicherheitswerkzeugen. Suricata schreibt mit Standardkonfiguration drei Dutzend Ereignistypen und richtet für sich keine Rotation ein — auf einem echten Server ergab das 15 GB in zwei Tagen. Dasselbe passiert mit audit.log und mit Debug-Protokollen in nginx;
  • Sicherungen, die auf derselben Platte landen und nie entfernt werden;
  • der apt-Cacheapt clean gibt gelegentlich ein paar Gigabyte zurück.

Ein Wort zu /boot

Eine kleine Partition, die sich mit alten Kerneln füllt. Die Website legt sie nicht selbst lahm, dafür bringt sie Updates zum Stillstand: Der neue Kernel lässt sich nicht installieren, und dahinter bleibt die gesamte Paket-Warteschlange hängen. Behoben mit apt autoremove --purge, vorgebeugt durch die automatische Entfernung ungenutzter Kernel in den Einstellungen der automatischen Updates.

SMART: welche Werte zählen

Zunächst eine Einschränkung: Auf einem virtuellen Server ist SMART meist nicht verfügbar — die Platte ist virtuell, die physische darunter sehen Sie nicht. Das ist kein Fehler, es gibt schlicht keine Daten. Alles Folgende betrifft dedizierte Server und eigene Hardware.

sudo smartctl -a /dev/sda

Die Zeile SMART overall-health self-assessment test result: PASSED ist kein Grund zur Entspannung: Sie bleibt praktisch bis zum Ausfall grün. Anzusehen sind die konkreten Zähler:

  • 5, Reallocated_Sector_Ct — umgelagerte Sektoren. Nicht null heißt, die Platte baut bereits ab; steigt der Wert, tauschen Sie sie ohne Aufschub;
  • 197, Current_Pending_Sector — Sektoren, die nicht gelesen werden können und auf eine Entscheidung warten. Der beunruhigendste von allen: Meist ist ein Teil der Daten schon nicht mehr zu retten;
  • 198, Offline_Uncorrectable — dasselbe, durch eine Prüfung bestätigt;
  • SSD: Percentage Used / Media_Wearout_Indicator — die verbrauchte Schreiblebensdauer. Eine vorhersehbare Größe, nach der ein Austausch geplant wird.

Temperatur und Betriebsstunden sagen für sich genommen dagegen nichts: Eine Platte mit fünf Jahren Laufzeit und Nullen bei den Fehlerzählern ist verlässlicher als eine neue mit einer 1 im Attribut 197.

Der Sinn des Beobachtens

All das oben ist eine Reaktion auf bereits Geschehenes. Dabei sind sowohl eine volllaufende Platte als auch SSD-Verschleiß langsame, durchaus vorhersehbare Vorgänge: Eine Belegungskurve über zwei Wochen nennt das Datum, an dem der Platz ausgeht, lange bevor es so weit ist. Der Unterschied zwischen „die Website liegt seit drei Uhr nachts“ und „am Donnerstag müssen die Protokolle weg“ besteht nur darin, die Zahl vor Augen zu haben. Wie das zusammengesetzt aussieht, zeigt die Demo-Seite unten.