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.
118 lines
5.6 KiB
Markdown
118 lines
5.6 KiB
Markdown
# 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
|