Neues Modul-Verzeichnis code/archive/ (Monorepo-Muster wie code/dms/). PostgreSQL-17-natives inkrementelles Backup (pg_basebackup --incremental, WAL-Summarization) statt WAL-Archiving, um den geteilten Testhost ohne Neustart umzustellen (summarize_wal=on per pg_reload_conf). Rolle nexarch_backup mit REPLICATION-Attribut angelegt. internal/backup: FullBackup/IncrementalBackup (pg_basebackup-Wrapper), Verify (vollstaendiges Lesen von base.tar.gz, gzip+tar, nicht nur Header), Rotate/ListGenerations (generationsbasiert, aeltere zuerst entfernt). cmd/backup-cli fuer systemd-Timer-Aufruf (deploy/systemd/ nexarch-archive-backup-*.timer, taeglich/stuendlich/taeglich). Auf 192.168.1.131 verifiziert: 4/4 Tests gegen echte Postgres-17-Instanz (kein Mock) - inkrementelle Sicherung real kleiner als Vollsicherung, Verifikation erkennt absichtlich beschaedigte Datei, Rotation entfernt nur die aeltesten Generationen. Zusaetzlich ECHT verdrahtet: backup-cli gebaut, 3 systemd-Timer installiert+aktiviert, jeder der drei Dienste einmal ueber systemctl start end-to-end ausgeloest (status=0/SUCCESS je Dienst) - nicht nur go test, sondern der reale Automatisierungspfad selbst geprueft. Siehe archive/docs/BAK-01-PRUEFPROTOKOLL.md fuer alle Pruefungsergebnisse. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
4.4 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)
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.