Files
archivmail/docs/MIGRATION_RUNBOOK.md
sysops 17633cb86c docs: Migrations-Runbook für Compliance-Erhalt-Check ergänzen (GoBD Punkt 10)
Baseline/Post-Vergleich, PROJ-18-Integritätscheck, Manticore-Konsistenz,
PROJ-52-Reconciliation und Byte-Vergleich als Ablauf nach jeder Schema-/
Index-/Tenant-Migration. Checklist-Punkt 10 auf Erfüllt gesetzt.
2026-07-04 12:14:30 +02:00

118 lines
5.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Migrations-Runbook archivmail
Bezug: GoBD/DSGVO-Checkliste (`docs/GOBD_DSGVO_CHECKLIST.md`), Punkt 10
"Migrationssicherheit". Ziel: nach jeder Schema-, Index- oder Storage-Migration
belegen, dass keine Mail verloren ging und die GoBD-Kernanforderungen
(Vollständigkeit, Unveränderbarkeit, Auffindbarkeit) weiterhin gelten.
Gilt für: `initSchema`/`ALTER TABLE`-Änderungen, Manticore-Reindex nach
Schema-Änderung, Storage-Format-Wechsel (z.B. Kompression, Verschlüsselung),
Tenant-Migrationen (`migrate-tenants`), Piler-Import (`import-piler`).
## Grundsatz
Jede Migration ist ein potenzieller Datenverlust-Vektor. Vor/während/nach
jeder produktiven Migration gilt: **Zählen, Prüfen, Belegen** — nicht nur
"Migration lief ohne Fehler durch".
## Ablauf
### 1. Vor der Migration (Baseline)
```bash
# Mail-Gesamtzahl + Tenant-Verteilung als Referenzwert
psql "$DSN" -c "SELECT tenant_id, COUNT(*) FROM emails GROUP BY tenant_id ORDER BY 1;"
# Aktuellen Reconciliation-Stand sichern (PROJ-52) — zeigt ob VOR der Migration
# bereits Lücken bestanden, damit die nicht fälschlich der Migration angelastet werden
archivmail reconcile --days 7 --dry-run 2>&1 | tee /var/log/archivmail/migration-pre-$(date +%F).log
# Backup, falls nicht ohnehin durch reguläres Backup abgedeckt (siehe devops-deploy)
pg_dump ... # Backup-Kommando gemäß bestehendem Backup-Runbook
```
Baseline-Zahlen (Gesamtzahl Mails, Zahl pro Tenant, Zeitpunkt) in den
Deploy-/Change-Log-Eintrag übernehmen (`DEVLOG.md` oder Commit-Message).
### 2. Migration ausführen
Reguläres Vorgehen laut `update.sh`/`install.sh` (Schema-Migrationen laufen
idempotent beim Start über `initSchema`, kein manueller Schritt nötig für
reine `ADD COLUMN IF NOT EXISTS`). Bei Index-Migrationen (z.B. neues Manticore-
Feld) ggf. `archivmail reindex` bzw. `archivmail reindex-tenant <id>` gezielt
ausführen.
### 3. Nach der Migration (Compliance-Erhalt-Check)
```bash
# 1. Zählvergleich — Gesamtzahl und Tenant-Verteilung MUSS mit Baseline übereinstimmen
psql "$DSN" -c "SELECT tenant_id, COUNT(*) FROM emails GROUP BY tenant_id ORDER BY 1;"
# Abweichung → STOP, nicht weiter deployen, Ursache klären (siehe "Bei Abweichung" unten)
# 2. Integritätscheck (PROJ-18) — läuft im Daemon ohnehin alle 5 Minuten automatisch
# (runIntegrityCheck in cmd/archivmail/main.go), nach einer Migration zusätzlich
# gezielt die Logs der ersten Läufe nach Neustart prüfen:
journalctl -u archivmail --since "-15min" | grep "integrity check"
# Erwartung: "integrity check: complete" mit failed=0
# 3. Manticore-Index-Konsistenz — Trefferzahl im Index sollte plausibel zur
# Mail-Zahl in Postgres passen (kein 1:1, da Anhänge/OCR-Text mitgezählt werden
# können, aber grobe Größenordnung muss stimmen)
mysql -h127.0.0.1 -P9306 -e "SELECT COUNT(*) FROM emails_global;"
# 4. Reconciliation-Report (PROJ-52) — Anomalie-Alert darf durch die Migration
# selbst NICHT ausgelöst werden (kein realer Rückgang, nur andere Quelle/Zeitpunkt)
archivmail reconcile --date $(date +%F)
# Dashboard/API /api/admin/reconciliation prüfen: kein unerwarteter alert:true
# 5. Stichprobe: eine bekannte Mail vor/nach Migration per ID abrufen und
# EML-Export vergleichen (Byte-Identität, PROJ-12 Unveränderbarkeit)
archivmail export --id <bekannte-mail-id> --out /tmp/post-migration-check.eml
diff /tmp/pre-migration-check.eml /tmp/post-migration-check.eml
```
### 4. Bei Abweichung
- Zahlendifferenz in Schritt 3.1 → Migration NICHT als abgeschlossen betrachten,
keine weiteren Schritte (Cron-Purge, Deploy auf zweiten Server) auslösen.
- Ursache eingrenzen: welcher Tenant/Zeitraum betroffen? Anhand Audit-Log
(`event_type IN ('import','mail_purged')`) im Migrationszeitraum abgleichen.
- Rollback nur nach Rücksprache — Datenbank-Restore aus Schritt 1-Backup,
nicht einfach erneut migrieren ohne Root-Cause.
- Vorfall im DEVLOG.md und ggf. als Audit-Log-Eintrag dokumentieren
(GoBD-Nachvollziehbarkeit: auch fehlgeschlagene Migrationsversuche gehören
ins Protokoll).
## Speziell: Tenant-Migration (`archivmail migrate-tenants`)
Zusätzlich zu obigem Ablauf:
- Vor der Migration: `SELECT COUNT(*) FROM emails WHERE tenant_id IS NULL;`
(Mails ohne Tenant-Zuordnung) als Baseline — nach der Migration darf diese
Zahl nur durch bewusste Zuordnung sinken, nie durch Datenverlust steigen.
- Tenant-Quotas (PROJ-29) nach Migration neu berechnen lassen, falls Mails
zwischen Tenants verschoben wurden.
## Speziell: Piler-Import (`archivmail import-piler`)
- Piler-seitige Mail-Zahl (aus Piler-Datenbank/Export) als externe Baseline
neben der internen archivmail-Zählung führen — reine interne Zählung
beweist nicht, dass alles aus Piler übernommen wurde.
- Reconciliation-Quelle `import` (PROJ-52) zeigt Tageszahlen des Imports;
gegen Piler-Log gegenprüfen.
## Speziell: Manticore-Schema-Änderung (z.B. neue Spalte, PROJ-50 `cc_addr`/`bcc_addr`)
- `ensureColumn`-Migration ist idempotent, aber NICHT rückwirkend befüllend
für bereits archivierte Mails (nur neue/reindexierte Dokumente bekommen den
Wert). Nach Schema-Änderung: `archivmail reindex` für Bestandsdaten planen,
wenn das neue Feld auch für alte Mails durchsuchbar sein soll — sonst
in der jeweiligen Feature-Spec als bekannte Deviation vermerken (siehe
PROJ-50, BCC-Deviation).
## Verweis
- PROJ-18 (Integritätsprüfung, SHA-256, alle 5 Minuten automatisch im Daemon)
- PROJ-52 (Vollständigkeits-Reconciliation, täglicher Report)
- PROJ-19 (Piler-Import), PROJ-30 (Xapian→Manticore-Migration) — historische
Migrationen, an denen dieses Runbook sich orientiert