restic statt Eigenbau (Content-defined Chunking fuer Dedup, verschluesseltes Repository ab Werk, geprueftes Tooling). internal/objectbackup wrapt restic init/backup/check/forget ueber os/exec, cmd/objectbackup-cli fuer systemd-Timer (stuendliche Sicherung, woechentliche Vollstaendigkeitspruefung, taegliche Rotation). Auf 192.168.1.131 real verifiziert (kein Mock): zweiter Lauf gegen unveraenderten Bestand ueberraegt nichts (files_new=0), zwei identische Dateien erzeugen nachweislich nur 1 data_blob (echter Dedup-Nachweis), absichtlich gekipptes Byte in einer Pack-Datei wird von check --read-data zuverlaessig erkannt. Echt verdrahtet: 3 systemd-Timer installiert+ aktiviert, jeder Dienst einmal end-to-end via systemctl start ausgeloest. Im selben Rutsch BAK-01-Fund korrigiert: NEXARCH_BACKUP_DIR zeigte auf /var/backups/nexarch (Root-Dateisystem, kein Dataset) statt auf das persistente ZFS-Dataset /var/nexarch-archiv - korrigiert, erneut ausgeloest, landet nachweislich am richtigen Ort. objectbackup-cli-Repository liegt von Anfang an korrekt dort. Siehe archive/docs/BAK-02-PRUEFPROTOKOLL.md fuer alle Pruefungsergebnisse. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
4.8 KiB
BAK-01 – Prüfprotokoll: Datenbank-Backup-Strategie
Welle 1, keine Vorbedingungen. Neues Modul-Verzeichnis code/archive/
(gleiches Monorepo-Muster wie code/dms/), eigenes Go-Modul
gitea.perlbach24.de/scripte/nexarch/archive.
Grundsatzentscheidung: PostgreSQL-17-natives inkrementelles Backup
pg_dump kennt nur logische Vollsicherungen — "inkrementell" im Sinne des
Tickets erfordert das physische Backup-Verfahren. Gewählt: PostgreSQL 17s
natives pg_basebackup --incremental (WAL-Summarization), NICHT klassisches
WAL-Archiving (archive_mode), weil letzteres einen Neustart der
(geteilten, auch von Core/DMS-Tests genutzten) Postgres-Instanz auf
192.168.1.131 erfordert hätte. Stattdessen summarize_wal = on gesetzt —
nur ein pg_reload_conf(), kein Neustart, keine Unterbrechung laufender
Verbindungen (per Health-Check nach der Änderung bestätigt).
Voraussetzung geschaffen: Rolle nexarch_backup mit REPLICATION-Attribut
angelegt (Postgres verlangt eine Replikationsverbindung für
pg_basebackup), pg_hba.conf erlaubte lokale Replikationsverbindungen
bereits.
Umsetzung
internal/backup.FullBackup/IncrementalBackup— rufenpg_basebackupüberos/execauf, Ergebnis landet in einer Generationsstruktur (<BackupDir>/<Generation>/full/bzw..../incremental/<ID>/).internal/backup.Verify— öffnetbase.tar.gzvollständig (gzip- UND tar-Stream, jeder Eintrag bis zum Ende gelesen, nicht nur Kopfdaten) — Akzeptanzkriterium 2: Verifikation auf Lesbarkeit, nicht nur Erstellung.internal/backup.Rotate/ListGenerations— Generationen sind nach Zeitstempel-ID sortierbar,Rotateentfernt die ältesten bis aufkeepkomplett (inklusive aller abhängigen Inkremente).cmd/backup-cli—full/incremental/rotate, aufgerufen von systemd-Timern (deploy/systemd/nexarch-archive-backup-*.timer) — "automatisiert nach Zeitplan" (Akzeptanzkriterium 1) entsteht durch die Timer-Definition, kein zusätzlicher Dauerprozess nötig.
Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Sicherung gegen Testdatenbank erfolgreich erstellt und verifiziert | bestanden — TestFullBackup_CreatesVerifiedBackup gegen die echte Postgres-17-Instanz auf 192.168.1.131 (kein Mock), zusätzlich TestIncrementalBackup_IsSmallerThanFull: inkrementelle Sicherung real deutlich kleiner als Vollsicherung (167 KB vs. 16 MB bei der ersten manuellen Probe) — beweist echte inkrementelle Übertragung, nicht nur eine zweite Vollsicherung |
| 2 | Verifikation erkennt eine absichtlich beschädigte Sicherungsdatei | bestanden — TestVerify_DetectsCorruptedFile: 64 Bytes in der Mitte von base.tar.gz gekippt, Verify schlägt danach fehl (unbeschädigt zuvor erfolgreich) |
| 3 | Rotationsregel entfernt nachweislich nur die ältesten Generationen | bestanden — TestRotate_RemovesOnlyOldestGenerations: 5 Generationen, keep=2, exakt die 3 ältesten entfernt, die 2 neuesten nachweislich unangetastet |
Echte Verdrahtung auf 192.168.1.131 (nicht nur Testcode)
Anders als die zuletzt in DMS gefundenen "Baustein existiert, ist aber nirgends verdrahtet"-Fälle (FDN-03/FDN-09 gegen Core) wurde hier die komplette Kette tatsächlich installiert und ausgeführt:
backup-cligebaut nach/opt/nexarch-archive/bin//etc/nexarch/archive-backup.envmit den Verbindungsdaten (0600)- 3 systemd-Timer installiert und aktiviert (
enable --now): Vollsicherung täglich 02:00 UTC, Inkrement stündlich, Rotation täglich 03:00 UTC (systemctl list-timersbestätigt alle drei scharf) - Jeder der drei Dienste (
full/incremental/rotate) einmal manuell übersystemctl startausgelöst (nicht nurgo testdirekt) — alle drei mitstatus=0/SUCCESS, Journal bestätigt inhaltlich korrekte Ausgabe (Vollsicherung erstellt+verifiziert, Inkrement erstellt+verifiziert gegen die richtige Vorgänger-Generation, Rotation lief ohne Fehler)
Build/Test-Ergebnis (192.168.1.131, make check)
go build ./... -> clean
go vet ./... -> clean
golangci-lint run ./... -> 0 issues
go test ./... -p 1 -count=1 -> 4/4 Tests ok, 0 Fehlschläge (echter Postgres 17, kein Mock)
Nachtrag (BAK-02-Sitzung): Backup-Zielverzeichnis korrigiert
NEXARCH_BACKUP_DIR zeigte ursprünglich auf /var/backups/nexarch
(Root-Dateisystem des Containers, kein dediziertes Dataset) — korrigiert auf
/var/nexarch-archiv/backups/postgres (persistentes ZFS-Dataset), siehe
docs/BAK-02-PRUEFPROTOKOLL.md Abschnitt „Korrektur an BAK-01" für Details.
Vollsicherung nach der Korrektur erneut über systemd ausgelöst, landet
nachweislich am neuen Ort.
Gesamtergebnis
Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt — inklusive tatsächlicher systemd-Timer-Installation und manuell ausgelöstem End-to-End-Lauf aller drei Dienste auf dem Testhost, nicht nur isolierter Testcode.