Zum Inhalt springen
Monitoring & Notfall

Wenn die Platte voll läuft: Shop-Speicher überwachen

Eine volle Datenpartition erzeugt keinen Ausfall, sondern hängende Bestellungen. Welche Verzeichnisse wachsen, welche Schwelle greift, welcher Turnus hilft.

14 Min. Lesezeit MonitoringSpeicherplatzKapazitätWartung

Kurz und einfach erklärt

Läuft der Speicher Ihres Servers voll, fällt der Shop oft nicht sichtbar aus. Er lädt weiter. Aber Bestellungen bleiben hängen.

Der Beitrag zeigt, welche Daten im Shop wachsen. Er zeigt auch, wie man den Speicher überwacht.

Man legt eine Grenze fest. Wird sie erreicht, gibt es einen Alarm. Außerdem räumt man in festen Abständen auf.

Wir überwachen den Speicher Ihres Shops und legen einen Plan zum Aufräumen fest.

Eine volle Datenpartition erzeugt selten einen sauberen Ausfall. Der Shop antwortet weiter, der Katalog lädt, die Verfügbarkeitsprüfung meldet HTTP 200 - nur schreibt die Datenbank keine Zeile mehr, die Bestellung bleibt im Zwischenstand hängen und die Bestätigung geht nie hinaus. Speicherplatz ist deshalb kein Aufräumthema für den Jahreswechsel, sondern ein eigener Messwert mit Schwelle, Alarm und festem Turnus. Dieser Beitrag zeigt die vier Quellen, die im Shop unbemerkt wachsen, warum die Schwelle in Prozent gehört und nicht in Gigabyte, worin sich eine volle Platte von einer erreichten Quota unterscheidet und welche Aufräumroutinen in den Wartungsplan gehören.

Das Wichtigste in Kürze

  • Läuft die Datenpartition voll, meldet der Shop keinen Ausfall: Er antwortet weiter und verliert Schreibvorgänge. Die Datenbank bricht in diesem Zustand nicht ab, sondern prüft einmal pro Minute (MySQL 8.4 Reference Manual), ob wieder Platz vorhanden ist.
  • Die vier stillen Wachstumsquellen sind Binärlogs, Sitzungsdaten, Cache und temporäre Ablage sowie erzeugte Dokumente und Bildableitungen. Ihre Standardwerte stehen fest, nur hat sie im Shop niemand gesetzt: Binärlogs bleiben voreingestellt 30 Tage (MySQL 8.4 Reference Manual) liegen.
  • Die Schwelle gehört in Prozent, weil jede Erweiterung der Platte sie sonst still verschiebt. Dazu kommt eine Reserve, die der Shop nie sieht: ext4 legt beim Anlegen des Dateisystems voreingestellt 5 % (mke2fs(8)) der Kapazität für den Systemnutzer beiseite.
  • Volle Platte und erreichte Quota sehen im Fehlerbild gleich aus und verlangen verschiedene Antworten. Erst die Unterscheidung macht aus einem Alarm eine Handlung, und erst der datierte Aufräumturnus macht aus der Handlung eine Routine.

Warum eine volle Platte kein Ausfall ist

Ein Ausfall hat den Vorteil, dass er auffällt. Die Seite antwortet nicht, die Verfügbarkeitsprüfung schlägt an, jemand steht auf. Eine volle Datenpartition verhält sich anders, weil Lesen keinen Platz braucht: Der Katalog erscheint, die Suche antwortet, der Warenkorb füllt sich. Erst beim Schreiben - Bestellung anlegen, Bestand fortschreiben, Zahlungsstatus vermerken, Sitzung sichern - kippt das Verhalten, und zwar nicht mit einer Fehlerseite, sondern mit Warten.

Die Datenbank tut dabei genau das, was ihre Dokumentation beschreibt. Läuft die Platte beim Schreiben voll, wartet der Server, statt abzubrechen, und prüft einmal pro Minute (MySQL 8.4 Reference Manual), ob wieder Platz vorhanden ist. Parallel schreibt er alle 10 Minuten (MySQL 8.4 Reference Manual) einen Hinweis in sein Fehlerprotokoll. Betroffen sind nicht nur Tabellen: Die Dokumentation nennt ausdrücklich auch Schreibvorgänge in die Binärlogs (MySQL 8.4 Reference Manual) und in deren Indexdatei. Wer in dieser Minute im Checkout steht, sieht einen Ladebalken.

Der Alarm, der nie kommt

Eine Prüfung auf HTTP 200 sieht diesen Zustand nicht, eine Prüfung auf Antwortzeit sieht ihn zu spät, und eine Prüfung auf Fehlerrate sieht ihn gar nicht, solange der Server geduldig wartet. Sichtbar wird er über zwei Messwerte, die unabhängig vom Shop erhoben werden: der belegte Anteil der Datenpartition und das Alter des ältesten unbearbeiteten Vorgangs. Wie beides in eine Alarmkette gehört, steht im Beitrag zum Log-Monitoring für Shops.

Die vier Quellen, die im Shop unbemerkt wachsen

Speicher wächst selten dort, wo man ihn vermutet. Produktbilder und Dateianhänge sind sichtbar, werden geplant und fallen im Zweifel sofort auf. Die vier Quellen, die eine Partition tatsächlich füllen, sind unsichtbar, weil sie zum normalen Betrieb gehören: Binärlogs der Datenbank, Sitzungsdaten, Cache und temporäre Ablage sowie erzeugte Dokumente wie Rechnungen und Bildableitungen. Keine davon taucht in einer Bestandsaufnahme auf, die nach großen Dateien sucht, denn alle vier bestehen aus vielen kleinen.

Die Binärlogs sind der ruhigste und zugleich gierigste Posten. Sie protokollieren jede Änderung an den Daten und sind die Grundlage für Replikation und für die Wiederherstellung auf einen Zeitpunkt - niemand will sie abschalten. Voreingestellt bleiben sie 30 Tage (MySQL 8.4 Reference Manual) liegen, und entfernt werden sie beim Start und beim Leeren des Binärlogs (MySQL 8.4 Reference Manual), nicht laufend. Ein Shop mit lebhaftem Lagerabgleich schreibt über einen Monat hinweg damit ein Vielfaches seiner eigentlichen Datenmenge auf dieselbe Partition.

QuelleStandardwert laut DokumentationWas daraus wächstWas in den Wartungsplan gehört
Binärlogs der DatenbankAufbewahrung 30 Tage (MySQL 8.4)Mit jedem Schreibvorgang, unabhängig von der Größe des DatenbestandsAufbewahrung an das Wiederherstellungsziel koppeln, nicht an die Voreinstellung
SitzungsdatenLebensdauer 1440 Sekunden, Aufräumlauf mit 1 zu 100 (PHP Manual)Mit jedem Besuch, auch ohne Bestellung; Suchmaschinen zählen mitEigener Ablageort, eigener Aufräumlauf, eigene Messung
Cache und temporäre AblageKein systemweiter Standardwert, je Anwendung verschiedenBei jedem Katalogumbau und jeder Neuerzeugung; alte Stände bleiben liegenNach jedem Bau räumen, Alter statt Größe als Kriterium
Erzeugte Dokumente und BildableitungenKeine Voreinstellung, Aufbewahrung folgt dem SteuerrechtLinear mit Bestellungen und Artikeln, Ableitungen je Format und BreiteGetrennter Ablageort, Aufbewahrung schriftlich festgehalten
Systemprotokoll (journald)10 % des Dateisystems, gedeckelt auf vier Gigabyte (journald.conf(5))Mit Fehlern und mit Last; im Störfall am schnellstenFeste Obergrenze setzen, statt den Standardwert wirken zu lassen

Die Tabelle zeigt den gemeinsamen Nenner: Keine dieser Quellen kennt den Shop. Sie kennen nur ihre eigene Voreinstellung, und die ist für irgendeinen Server gedacht, nicht für diesen Server mit dieser Partition und diesem Bestellaufkommen. Wie eng Datenbankpflege und Speicherbedarf zusammenhängen, zeigt der Beitrag zur Datenbankwartung im Shop.

Die Schwelle gehört in Prozent, nicht in Gigabyte

Eine Schwelle in Gigabyte ist eine Momentaufnahme. Sie stimmt für die Partition, auf der sie gesetzt wurde, und wird beim nächsten Ausbau still falsch: Aus "Alarm bei 20 GB frei" wird auf einer großen Platte eine Warnung, die eine Stunde vor dem Stillstand eintrifft, und auf einer kleinen eine Warnung, die dauerhaft ansteht und deshalb irgendwann abgeschaltet wird. Ein Anteil in Prozent bleibt über jeden Ausbau hinweg vergleichbar und lässt sich zwischen Systemen übertragen.

Dazu kommt ein Detail, das die Rechnung verschiebt. ext4 legt beim Anlegen des Dateisystems voreingestellt 5 % (mke2fs(8)) der Kapazität für den Systemnutzer beiseite; dieser Anteil steht dem Shop nie zur Verfügung. Auf einer reinen Datenpartition ist er eher Reserve als Notwendigkeit und lässt sich nachträglich absenken. Anders liegt der Fall beim Verhältnis von Inodes zu Kapazität: Es wird beim Anlegen festgelegt und lässt sich danach nicht mehr ändern (mke2fs(8)). Eine Partition voller kleiner Dateien kann deshalb keine Datei mehr aufnehmen, während die Belegung noch 60 Prozent zeigt.

Zwei Schwellen, zwei Reaktionen

80 Prozent (Projekterfahrung) belegt ist eine Aufgabe für den nächsten Werktag: nachsehen, was gewachsen ist, und den Aufräumturnus nachziehen. 90 Prozent belegt ist ein Fall für die Rufbereitschaft, weil der Abstand zwischen Warnung und Stillstand dann in Stunden gemessen wird. Beide Werte sind Betriebserfahrung und keine Vorgabe aus einer Norm; entscheidend ist, dass die obere Schwelle Abstand zur vollen Platte lässt und die untere früh genug greift, um ohne Wartungsfenster auszukommen.

Ebenso wichtig ist, was die Schwelle auslöst. Ein Alarm, der nur "Platte fast voll" sagt, erzeugt eine Suche. Ein Alarm, der die drei dicksten Verzeichnisse, ihr Wachstum seit gestern und den Zeitpunkt der letzten Aufräumroutine mitliefert, erzeugt eine Entscheidung. Der Unterschied kostet einmal eine halbe Stunde Einrichtung und spart in jedem Störfall die erste Viertelstunde - genau die, in der im Notfall-Support sonst nur Kontext hergestellt wird.

Volle Platte oder erreichte Quota

Im Fehlerbild sehen beide Zustände gleich aus: Schreiben schlägt fehl oder hängt. Die Ursache ist verschieden, und damit auch die Antwort. Eine volle Partition betrifft alles, was auf ihr liegt - Datenbank, Sitzungen, Protokolle, Dokumente. Eine erreichte Quota betrifft genau ein Konto oder ein Verzeichnis, während daneben Platz frei ist und jede Messung der Partition eine gesunde Zahl liefert.

Im geteilten Hosting ist die Quota der Regelfall und aus genau diesem Grund tückisch: Das Dateisystem hat Platz, das Konto nicht. Wer in dieser Lage nur die Partition misst, sieht eine gesunde Zahl und einen kranken Shop. Deshalb gehören beide Messwerte in die Überwachung, jeweils mit eigener Schwelle und eigenem Empfänger. Dieselbe Trennung gilt für Datenbank-Quota, Postfach-Quota und den Ablageort der Sicherungen - drei Orte, an denen der Platz unabhängig voneinander ausgehen kann.

Binärlogs

Die Aufbewahrung bemisst sich am Wiederherstellungsziel, nicht an der Voreinstellung. Was länger liegt, als die Backup-Strategie verlangt, ist reiner Platzverbrauch.

Sitzungsdaten

Lebensdauer und Aufräumlauf sind zwei getrennte Einstellungen. Die erste sagt, wann eine Sitzung alt ist, die zweite, ob überhaupt jemand nachsieht.

Cache und Ableitungen

Bildableitungen entstehen je Format und Breite neu, alte Stände verschwinden nicht von selbst. Wie sich das eingrenzen lässt, steht im Beitrag zu WebP und AVIF im Shop.

Erzeugte Dokumente

Rechnungen wachsen linear mit dem Umsatz und unterliegen der Aufbewahrung. Sie gehören getrennt abgelegt, damit ein Aufräumlauf sie nie erreicht.

Temporäre Ablage

Abgebrochene Importe, halbe Ausleitungen, Reste aus Aktualisierungen: Der Ordner für Temporäres ist kein Selbstreiniger, sondern eine Ablage mit Gedächtnis.

Meldeweg

Jede Quelle braucht einen Empfänger. Ein Wert ohne Adressat ist eine Zahl in einer Übersicht, die im Störfall niemand öffnet.

Sechs Posten, sechs Zuständigkeiten - das klingt nach Aufwand und ist in der Praxis eine einmalige Einrichtung. Danach ist Speicher ein Messwert wie Antwortzeit oder Fehlerrate, und er verhält sich freundlicher als beide: Er ändert sich langsam und kündigt sich an. Wer ihn misst, bekommt Wochen Vorlauf, wo er sonst Minuten hat.

Standardwerte, die niemand gesetzt hat

Drei Beispiele zeigen, wie Voreinstellungen im Betrieb wirken. Sitzungsdaten gelten nach 1440 Sekunden (PHP Manual) als veraltet, aufgeräumt wird aber nur mit einer Wahrscheinlichkeit von 1 zu 100 (PHP Manual) je Anfrage - bei wenig Verkehr bleibt viel liegen, bei viel Verkehr wächst der Bestand schneller, als der Zufall ihn abträgt. Das Systemprotokoll nimmt sich voreingestellt 10 % (journald.conf(5)) des Dateisystems, gedeckelt auf vier Gigabyte. Ist diese Grenze erreicht, gibt es belegten Platz nicht wieder her (journald.conf(5)), sondern hört nur auf, weiteren zu belegen.

The thread is aborted the next time it checks the disk (in one minute).

MySQL 8.4 Reference Manual, B.3.3.4 How MySQL Handles a Full Disk

Der Satz beschreibt das Verhalten, das im Shop als "langsam" ankommt. Die Verbindung bleibt offen, der Vorgang ist weder abgelehnt noch abgeschlossen, und wenn der Prozess schließlich abgebrochen wird, steht ein halber Vorgang in der Datenbank. Genau solche Halbzustände tauchen später als fehlende Zahlung, doppelte Bestellung oder stille Fehler in Hintergrundjobs wieder auf - dann allerdings ohne erkennbaren Zusammenhang zur Platte.

kapazitaet-melden.sh
#!/bin/bash
# Kapazität je Partition und je Quota melden. Schwellen in Prozent, nicht in Gigabyte.
# Aufruf aus dem Wartungstakt, Ausgabe in eine Logdatei, Rückgabewert steuert den Alarm.

ZIEL="/var/www/shop"
WARN=80
KRITISCH=90
RC=0

# Belegter Anteil der Partition, wie ihn der Shop sieht (ohne Reserve des Systemnutzers).
belegt=$(df --output=pcent "$ZIEL" | tail -n1 | tr -dc '0-9')
echo "partition_belegt_prozent=$belegt"

if [ "$belegt" -ge "$KRITISCH" ]; then
  echo "ALARM Partition $ZIEL bei $belegt Prozent - Rufbereitschaft"
  RC=2
elif [ "$belegt" -ge "$WARN" ]; then
  echo "WARNUNG Partition $ZIEL bei $belegt Prozent - nächster Werktag"
  RC=1
fi

# Die drei dicksten Verzeichnisse benennen, damit der Alarm eine Handlung enthält.
du -x -m -d 1 "$ZIEL" 2>/dev/null | sort -rn | head -4 | while read -r mb pfad; do
  echo "verzeichnis: $mb MB  $pfad"
done

# Quota getrennt messen: Das Dateisystem kann Platz haben, das Konto nicht.
if command -v quota >/dev/null 2>&1; then
  quota -w -s 2>/dev/null | tail -n +3 | awk '{print "quota:", $1, "von", $2}'
else
  echo "quota: kein Quota-Werkzeug vorhanden - Wert nicht gemessen"
fi

# Ältestes Binärlog: Reicht es über die eingestellte Aufbewahrung hinaus, greift sie nicht.
aeltest=$(find /var/log/mysql -name 'binlog.*' -printf '%T@ %p\n' 2>/dev/null | sort -n | head -1)
echo "binlog_aeltestes=${aeltest:-nicht gemessen}"

exit "$RC"

Der feste Aufräumturnus

Aufräumen auf Zuruf ist kein Verfahren, sondern die Reaktion auf einen Alarm, den es nicht hätte geben müssen. Ein Turnus hat drei Eigenschaften: Er ist datiert, er ist protokolliert, und er kennt für jede Quelle ein Kriterium, das nicht "zu groß" heißt, sondern ein Alter oder eine Anzahl nennt. Nur dann bleibt er richtig, wenn sich der Verkehr verdoppelt.

  • Wöchentlich: Belegung je Partition und je Quota erfassen, Wachstum gegen die Vorwoche notieren. Eine einzelne Zahl sagt wenig, die Steigung sagt alles.
  • Wöchentlich: Aufbewahrung der Binärlogs gegen das Wiederherstellungsziel prüfen. Was länger liegt, als die Wiederherstellung zurückreicht, ist Ballast - siehe Disaster Recovery im Shop.
  • Monatlich: Sitzungsablage und temporäres Verzeichnis nach Alter räumen, nicht nach Größe. Das Kriterium bleibt damit auch bei wachsendem Verkehr richtig.
  • Monatlich: Bildableitungen gegen den Artikelbestand abgleichen; Ableitungen gelöschter Artikel bleiben sonst dauerhaft liegen und niemand vermisst sie.
  • Quartalsweise: Aufbewahrungspflichten und tatsächliche Ablage abgleichen, damit kein Aufräumlauf an aufbewahrungspflichtige Belege heranreicht - Einzelheiten im Beitrag zur DSGVO-konformen Datensicherung.
  • Nach jedem Bau und jedem größeren Import: Cache-Stände und Reste prüfen, bevor das Wartungsfenster endet und niemand mehr hinsieht.

Der Turnus gehört in dieselbe Liste wie Aktualisierungen und Sicherungen, also in den Wartungsvertrag. Nicht aus formalen Gründen, sondern weil Aufgaben ohne festen Platz im Kalender in genau der Woche ausfallen, in der es darauf angekommen wäre.

Vom Alarm zur Entlastung

Belegung, Wachstum seit der Vorwoche, die drei dicksten Verzeichnisse und der Zustand der Quota. Wer zuerst löscht, verliert die Spur und wiederholt denselben Vorfall in vier Wochen.

Die Reihenfolge ist nicht beliebig. Der teuerste Fehler in dieser Lage ist das schnelle Löschen von Binärlogs im Dateisystem: Danach ist Platz da, die Wiederherstellung auf einen Zeitpunkt aber nicht mehr möglich. Eine Sicherung, deren Wiederherstellung erst im Ernstfall geprüft wird, ist keine Sicherung, sondern eine Annahme; wie sich das belegen lässt, steht beim Backup-Service.

Was Aufbewahrung verlangt

Nicht alles, was Platz kostet, darf weg. Für steuerlich relevante Unterlagen staffelt § 147 Absatz 3 der Abgabenordnung die Fristen: Bücher und Aufzeichnungen sind zehn Jahre (Abgabenordnung) aufzubewahren, Buchungsbelege acht Jahre und die sonstigen dort genannten Unterlagen sechs Jahre. Für den Shop heißt das: Rechnungen und Buchungsbelege sind kein Kandidat für einen Aufräumlauf, sondern ein Posten, dessen Wachstum eingeplant und dessen Ablageort so gewählt wird, dass keine Routine ihn erreicht.

Die Gegenrichtung ist genauso wichtig: Was keiner Aufbewahrung unterliegt, braucht eine Obergrenze. Bei MariaDB ist die Aufbewahrung der Binärlogs anders voreingestellt als bei MySQL. Dort steht die Voreinstellung 0 (MariaDB Server Documentation), also keine zeitliche Begrenzung, der zulässige Bereich reicht bis 8553600 Sekunden (MariaDB Server Documentation), und entfernt wird beim Start und beim Rotieren des Binärlogs (MariaDB Server Documentation). Wer aus einer Anleitung für das eine System die Werte des anderen übernimmt, bekommt entweder eine Partition voller Protokolle oder eine Lücke in der Wiederherstellung.

Messwert statt Gefühl

Belegung und Wachstum je Partition, erhoben im selben Takt wie Antwortzeit und Fehlerrate. Erst die Steigung macht aus einer Zahl eine Vorhersage.

Getrennte Ablageorte

Datenbank, Protokolle, Dokumente und Cache auf einer Partition heißt: Ein Ausreißer legt alles still. Getrennt heißt: Ein Ausreißer legt eines still.

Turnus mit Datum

Jede Aufräumroutine hat einen Termin, ein Kriterium und einen Eintrag im Protokoll. Ohne Eintrag lässt sich später nicht unterscheiden, ob sie lief oder ausfiel.

Aufbewahrung geschützt

Aufbewahrungspflichtige Belege liegen dort, wo kein Aufräumlauf hinreicht. Das ist eine Frage der Ablage, nicht der Sorgfalt im Einzelfall.

Alarm mit Kontext

Die Meldung nennt die drei dicksten Verzeichnisse und das Wachstum seit gestern, sonst beginnt jede Störung mit derselben Suche.

Kapazität vorausgeplant

Aus dem Wachstum der letzten drei Monate ergibt sich der Zeitpunkt der nächsten Erweiterung. Planbar ist sie nur, solange sie nicht dringend ist.

Zusammen ergeben die sechs Punkte kein Projekt, sondern eine Routine. Im Monitoring hat Speicher das beste Verhältnis von Aufwand zu Wirkung: billig zu erheben, langsam in der Veränderung und in der Lage, eine Störung zu verhindern, die sonst im Checkout ankommt, bevor sie in einer Übersicht auffällt.

Kapazität im Wartungstakt

Speicherplatz ist der unauffälligste Messwert im Shop und einer der wenigen, die eine Störung Wochen vorher ankündigen. Wer ihn in Prozent misst, je Quelle eine Obergrenze setzt, den Aufräumturnus datiert und die Quota getrennt betrachtet, verwandelt einen Stillstand um vier Uhr morgens in eine Aufgabe am Dienstagvormittag. Der Rest ist Buchführung: Welche Partition wächst wie schnell, welche Aufbewahrung ist Pflicht, wann ist der nächste Ausbau fällig. Wie eng Kapazität mit anderen stillen Fehlerbildern zusammenhängt, zeigen der Beitrag zum Cache-Drift im Shop und die Auswertung im Checkout-Monitoring.

Quellen

Dieser Artikel stützt sich auf: MySQL 8.4 Reference Manual, B.3.3.4 How MySQL Handles a Full Disk sowie 19.1.6.4 Binary Logging Options and Variables; mke2fs(8) aus E2fsprogs 1.47.4; journald.conf(5) aus systemd; PHP Manual, Session Runtime Configuration; MariaDB Server Documentation, Replication and Binary Log System Variables; Abgabenordnung § 147. Die genannten Schwellen von 80 und 90 Prozent sind Projekterfahrung und keine Vorgabe aus einer Norm.

Verwandte Artikel

Monitoring & Notfall

Indexierbarkeit überwachen: wenn noindex live geht

Ein noindex aus dem Testsystem fällt oft erst auf, wenn der Umsatz einbricht. So entsteht eine Prüfkette aus fünf Stufen, die Abweichungen am selben Tag meldet.

17 Min. Lesezeit
Wartung & Updates

WordPress-Sicherheitsupdates: Was alte Zweige noch bekommen

WordPress 7.1.2 schloss eine kritische Lücke, der Fix kam als Gefälligkeit bis 4.7 zurück. Was ältere Zweige erhalten, was nicht und wann der Sprung fällig ist.

20 Min. Lesezeit
Sicherheit

Rabattcodes in der Black Week: Missbrauch früh erkennen

Rabattcodes in der Black Week schützen: Codelänge, Rate-Limit am Gutscheinfeld, Alarm bei Fehlversuchen und ein Neukundenrabatt, der Mehrfachkonten standhält.

21 Min. Lesezeit