194 lines
12 KiB
Markdown
194 lines
12 KiB
Markdown
# Automatische Speicherbereinigung
|
|
|
|
## Platznot vor dem Backup: Korrektur vom 21.09.2026
|
|
|
|
Der Mailbericht vom 20.09. nennt 55.823.183.174 benötigte und
|
|
47.615.086.592 verfügbare Bytes: Es fehlen 8.208.096.582 Bytes (7,64 GiB).
|
|
Die alte Bereinigung schützt dieselben drei lokalen Kopien wie die reguläre
|
|
Retention. Dadurch kann sie bereits vor dem nächsten Backup blockieren.
|
|
|
|
`SPACE_KEEP_LOCAL=1` setzt jetzt eine eigene Untergrenze für Platznot, auch bei
|
|
bestehender Konfiguration ohne diesen Eintrag. Die neuesten so vielen gültigen,
|
|
als hochgeladen markierten lokalen Sätze bleiben erhalten. `RETENTION_KEEP_LAST=3`
|
|
gilt weiterhin für die normale Retention und wird nicht verändert. Wer die alte
|
|
Grenze ausdrücklich beibehalten möchte, setzt `SPACE_KEEP_LOCAL=3`. Null ist
|
|
unzulässig. Die Reserve `MIN_FREE_GB=10` und die Snapshot-Schätzung bleiben bestehen.
|
|
|
|
Gelöscht wird ältester Satz zuerst, nur bis der Bedarf gedeckt ist und nur nach
|
|
vollständiger lokaler Inhaltsprüfung, Remote-Datei-/Größenvergleich und bytegenauem
|
|
Vergleich von Remote-Manifest und `COMPLETE`. Für die beiden kleinen Kontrolldateien
|
|
gelten dieselben begrenzten Versuche/Zeitlimits; Archive werden nicht heruntergeladen.
|
|
Die geschützten neuesten lokalen Kopien werden zuvor ebenfalls vollständig geprüft.
|
|
Ist eine davon beschädigt oder unvollständig, bleiben alle älteren Kandidaten
|
|
erhalten; ein bloßer `UPLOADED`-Marker genügt nicht als Rückfallabsicherung.
|
|
Signalisierte Abbrüche beenden die Bereinigung, statt weitere Kandidaten zu versuchen.
|
|
Nach jeder Entfernung wird der tatsächlich freie Platz neu gemessen. Mountpoints,
|
|
auch Bind-Mounts einzelner Dateien, werden nicht rekursiv gelöscht.
|
|
|
|
Das schafft Platz, wenn ausreichend bestätigte lokale Kopien vorhanden sind.
|
|
Bei geschützten Beständen, Remote-Fehlern oder einem zu kleinen Datenträger kann
|
|
die Software keinen sicheren Platz erzwingen: Sie bricht vor dem Writer-Stopp ab
|
|
und protokolliert Bedarf, Verfügbarkeit, Defizit sowie verbleibende Archivbestände
|
|
mit belegten Bytes und Schutzgrund. Nicht bestätigte Uploads bleiben erhalten.
|
|
Das Update führt diese Bereinigung bereits vor der Installation aus; sie ist
|
|
daher auch dann wirksam, wenn der bisher installierte Stand nicht mehr starten kann.
|
|
|
|
### Wenn die geschützten Bestände den Platz belegen
|
|
|
|
`preflight.log` beziehungsweise das Backup-Log zeigt, ob bestätigte lokale Sätze
|
|
oder unbestätigte/unklare Bestände übrig sind. Zunächst lesend prüfen:
|
|
|
|
```bash
|
|
sudo du -xhd2 /var/backups/app-backup
|
|
df -h /var/backups/app-backup
|
|
sudo find /var/backups/app-backup/archives -maxdepth 2 -name UPLOADED -printf '%h\n'
|
|
```
|
|
|
|
Unbestätigte vollständige Sätze müssen außerhalb dieses automatischen Ablaufs
|
|
gesondert geprüft und offsite veröffentlicht oder auf einen anderen Datenträger
|
|
verschoben werden. Keinen `UPLOADED`-Marker manuell vortäuschen. Reicht auch danach
|
|
der Platz nicht, das Backup-Dateisystem erweitern oder `WORKDIR`/`STAGING_ROOT`/
|
|
`ARCHIVE_DIR` auf einen ausreichend großen dedizierten Datenträger umstellen.
|
|
Eine Verlagerung erfolgt bei gestoppten Backup-/Restore-/Update-Aufträgen; vorhandene
|
|
Sätze, Besitzrechte und Modus 700 müssen erhalten bleiben. Anschließend
|
|
`--prepare-space` und `--check` mit der neuen Konfiguration ausführen.
|
|
Weder geschützte Recovery-Daten noch die letzte bestätigte lokale Sicherung
|
|
werden als Ausweg automatisch gelöscht.
|
|
|
|
Der auf Gemini gemeldete Abbruch vom 12.09.2026 erfolgte nach dem erfolgreichen
|
|
Wiederanlauf der Dienste, während der Kompression: Unter `/var` waren nur noch
|
|
9,2 GiB frei, die konfigurierte Reserve beträgt 10 GiB. Rund 29 GiB Staging und
|
|
91 GiB Archive belegten denselben Datenträger. Eine reine Reserveprüfung vor dem
|
|
Backup konnte den zusätzlichen Platzbedarf nicht erkennen.
|
|
|
|
## Neuer Ablauf
|
|
|
|
Backup, Restore und Update teilen sich dieselbe Sperre. Vor einem echten Backup
|
|
oder der Update-Vorbereitung werden folgende Schritte ausgeführt:
|
|
|
|
1. Einen unterbrochenen, eindeutig markierten monatlichen Restore-Test bereinigen.
|
|
Eine möglicherweise noch laufende Test-DB wird zuerst entfernt. Ist Docker
|
|
dafür nicht erreichbar, bleiben ihre Dateien geschützt; die Bereinigung meldet
|
|
einen Fehler und der Bereinigungsdienst versucht es erneut.
|
|
2. Erkannte Backup-Arbeitsreste früherer Läufe entfernen. Dazu müssen privates
|
|
Verzeichnis, Laufname, `meta/run-id.txt` und `meta/format.txt` zusammenpassen.
|
|
Das zugehörige unvollständige Archivverzeichnis wird ebenfalls entfernt.
|
|
Damit ist der im Gemini-Log gezeigte Fehlerfall auch aus älteren Paketständen
|
|
erkennbar. Unbekannte Ordner werden nicht anhand ihres Alters gelöscht.
|
|
3. Den Snapshot-Bedarf mit einem rsync-Trockenlauf unter denselben Excludes wie
|
|
beim Backup und einer lesenden DB-Größenabfrage schätzen. Die Planung enthält
|
|
Dateisystem-/Archiv-Metadaten, zusätzliche Dump-/Wachstumsreserven und bei
|
|
gemeinsamem Dateisystem Platz für Snapshot plus Archiv. Erst nach erfolgreicher
|
|
Platzprüfung werden produktive Writer angehalten.
|
|
4. Bei Platzmangel ältere geeignete lokale v2-Sätze prüfen. Nur Sätze mit gültigem
|
|
Manifest, `COMPLETE` und lokalem `UPLOADED` kommen infrage. Die neuesten
|
|
`SPACE_KEEP_LOCAL` geeigneten Kopien bleiben geschützt (Default und Minimum eins).
|
|
Ältere Kandidaten werden lokal vollständig validiert und mit
|
|
`rclone check --size-only` inklusive Manifest und `COMPLETE` auf
|
|
Remote-Dateiexistenz und passende Größen geprüft (ohne Archivdownload). Erst bei erfolgreicher Prüfung wird die lokale
|
|
Kopie entfernt; zusätzlich müssen Remote-Manifest und `COMPLETE` bytegenau
|
|
mit den lokalen Dateien übereinstimmen. Fehlende Remote-Dateien oder Größenabweichungen verhindern die Löschung.
|
|
Gleich große Inhaltsbeschädigungen werden erst beim Restore erkannt. Es wird nur so lange bereinigt, bis der geplante Platz reicht.
|
|
|
|
Diese Offsite-Vergleiche verwenden ebenfalls die begrenzten Prüfanläufe und
|
|
Zeitlimits aus [REMOTE_READBACK.md](REMOTE_READBACK.md). Ein fehlgeschlagener
|
|
Vergleich erlaubt auch nach mehreren Versuchen keine lokale Löschung.
|
|
|
|
Die Platzbereinigung benötigt keinen vorherigen neuen Sicherungslauf. Sie darf
|
|
das lokale Aufbewahrungsalter und `RETENTION_KEEP_LAST` unterschreiten,
|
|
**niemals die eigene Mindestanzahl `SPACE_KEEP_LOCAL`**.
|
|
Sie verändert keine Offsite-Daten. Die normale Altersretention nach einem neuen
|
|
erfolgreichen Backup bleibt davon getrennt. `--no-retention` im Update unterdrückt
|
|
die Altersretention, erlaubt aber weiterhin die hier beschriebene Platzbereinigung.
|
|
|
|
Nach dem Ende des Kopierfensters werden Dienste wie bisher wieder gestartet.
|
|
Während der Kompression wird jede Komponente vollständig als Archiv geprüft;
|
|
danach wird ihre unkomprimierte Arbeitskopie sofort entfernt. Die kleinen
|
|
Metadaten bleiben bis zum Abschluss für Veröffentlichung und Wiedererkennung.
|
|
Der Mailbericht erfasst die ursprünglichen Staging-Größen vor dieser Freigabe.
|
|
|
|
Bei einem fehlgeschlagenen Backup werden dessen Staging und unvollständige Archive
|
|
nach erfolgreicher Dienstwiederherstellung ebenfalls entfernt. Der Fehler bleibt
|
|
im Status und Bericht sichtbar. Ein vollständiger lokaler Satz, dessen Upload
|
|
fehlgeschlagen ist, bleibt erhalten.
|
|
|
|
## Grenzen der automatischen Löschung
|
|
|
|
Folgende Daten bleiben geschützt:
|
|
|
|
- vollständige lokale Sätze ohne bestätigten Upload;
|
|
- die neuesten `SPACE_KEEP_LOCAL` geeigneten lokalen Sicherungen;
|
|
- ein `.partial`-Verzeichnis, das bereits einen `COMPLETE`-Marker enthält;
|
|
- sämtliche Arbeitsreste bei vorhandenem `recovery-*.json` oder angefangener
|
|
Recovery-Datei: zunächst muss der Dienst-/Restore-Zustand geklärt werden;
|
|
- manuell entpackte Restores, historische v1-Archive und unbekannte Verzeichnisse;
|
|
- Symlink-Ziele, eingehängte Dateisysteme, fremde Container, Images und Volumes.
|
|
|
|
Es gibt kein `docker system prune`, keine pauschale Löschung von `/var/backups`
|
|
und keine automatische Entfernung von Paketrollback-Sicherungen. Die entfernte
|
|
lokale Historie wird durch einen Paketrollback nicht wiederhergestellt; ihre
|
|
geprüften Offsite-Kopien stehen weiterhin zum Download bereit.
|
|
|
|
Scheitert die Platzbeschaffung an diesen Grenzen, beendet sich das Backup vor
|
|
dem Anhalten der Writer mit einer konkreten Platzmeldung. Bei Änderungen durch
|
|
andere Prozesse oder ungewöhnlich wachsenden Dumps können spätere Prüfungen
|
|
trotzdem scheitern. Die Schätzung ist keine Dateisystemquote. Fehler bei produktiver
|
|
Dienstwiederherstellung oder einem echten Restore erfordern weiterhin einen
|
|
Admin; sie werden nicht durch automatisches Löschen oder Neustarten verdeckt.
|
|
|
|
Ein bereits vollständig lokaler, aber noch nicht hochgeladener Satz wird nicht
|
|
automatisch nachträglich hochgeladen. Solche Sätze bleiben bei wiederholten
|
|
Remote-Ausfällen erhalten und können einen Eingriff nötig machen.
|
|
|
|
## Restore und MariaDB-Vorbereitung
|
|
|
|
Der monatliche Restore-Test verarbeitet alle Komponenten einzeln. Standardmäßig
|
|
begrenzt `RESTORE_TEST_MAX_WORK_GB=0` das Arbeitsvolumen anhand der tatsächlich
|
|
freien Kapazität bei mindestens `RESTORE_TEST_MIN_FREE_GB=2` GiB Reserve. Ein
|
|
positiver Wert setzt zusätzlich eine feste Obergrenze. Die Update-Option
|
|
`--enable-restore-test` aktiviert den Test und setzt ausdrücklich das adaptive
|
|
Budget; ohne diese Option bleibt eine bestehende feste Grenze erhalten.
|
|
|
|
Vor Download und Entpacken versucht der Test bei Platzmangel die oben beschriebene
|
|
lokale Bereinigung. Während des laufenden Imports werden Grenzen überwacht;
|
|
bei Unterschreitung wird abgebrochen und bereinigt. Dabei werden nicht nebenher
|
|
Sicherungen gelöscht. Vorbereitete MariaDB-Images bleiben zur Wiederverwendung
|
|
erhalten. Ein Image-Download prüft zusätzlich Platz auf dem Docker-Dateisystem.
|
|
|
|
`app-restore.sh --remote-run ... --verify-only` lädt jeweils nur ein komprimiertes
|
|
Archiv herunter, validiert es vollständig und entfernt es sofort. Lokale
|
|
`--verify-only`-Aufrufe prüfen den Satz direkt ohne Kopie. Bei Fehlern werden die
|
|
eigenen Prüftemporärdateien entfernt; neue abgebrochene Download-Prüfungen sind
|
|
durch einen Marker beim nächsten Lauf erkennbar. Manuelle `--extract-only`- und
|
|
produktive `--apply`-Restores benötigen weiterhin Platz für ihren vollständigen
|
|
Arbeitsbestand; zusätzliche Kopier- und Entpackgrößen werden vorab geprüft. Ihre Daten werden bei Fehlern zur Prüfung erhalten und nicht
|
|
automatisch als Testreste gelöscht. Eine ausgewählte lokale Restore-Quelle ist
|
|
von der Platzbereinigung ausgenommen.
|
|
|
|
## Vorgehen auf Gemini
|
|
|
|
Das neue Update-Paket wie in [UPDATE_ANLEITUNG.md](UPDATE_ANLEITUNG.md) mit
|
|
`--enable-restore-test` starten. Es bereinigt vor der Vorprüfung erkannte alte
|
|
Arbeitsreste, bereitet MariaDB vor und führt Backup mit Remote-Dateiprüfung
|
|
aus. Nach erfolgreicher Update-Abnahme aktiviert es die Timer; der vollständige
|
|
Restore-Test folgt beim Monatstermin. Der alte fehlgeschlagene Update-Ordner
|
|
bleibt als Diagnose-/Rollback-Nachweis erhalten; ein pauschales `rm` ist unnötig.
|
|
|
|
Nach bereits erfolgter Installation kann die Platzvorbereitung separat gestartet
|
|
werden. Dieser Befehl **bereinigt tatsächlich** nach den obigen Regeln, erstellt
|
|
aber kein Backup und hält keine Anwendungen an:
|
|
|
|
```bash
|
|
sudo bash /usr/local/sbin/app-backup.sh --prepare-space
|
|
sudo bash /usr/local/sbin/app-backup.sh --check
|
|
df -h /var/backups/app-backup
|
|
```
|
|
|
|
`--check` allein bleibt eine Prüfung ohne Bereinigung. Vollständige
|
|
lokale Inhaltsprüfungen können dauern; remote werden nur Dateiexistenz und Größen geprüft. Der Starter
|
|
nennt sein Verzeichnis mit `preflight.log`; der spätere Worker schreibt `update.log`
|
|
und `result.txt`. `SUCCESS` im aktuellen `result.txt` bestätigt das Update; der
|
|
Restore-Teststatus ist ein separater Nachweis nach dem Monatslauf. Scheitert ein Update trotz der
|
|
sicheren Bereinigung, bleiben die Timer nach begonnener Installation gestoppt;
|
|
der Fehler muss behoben und das Paket erneut ausgeführt werden.
|