Mail-Graveyard/db-rename-brief.md
2026-07-14 19:27:28 +02:00

4.1 KiB
Raw Permalink Blame History

Codex-Brief — DB-Namen-Altlast beseitigen (stiller Daten-GAU)

Priorität: vor der ersten echten @dr-gold.de-Migration. Das ist kein Kosmetikproblem.

Der Befund

Stelle db_path
config.json.example mail-graveyard.db
INSTALL.md (cp config.json.example config.json) mail-graveyard.db
Code-Default in ConnectDB (02-database.go) mail-graveyard.db
LIVE auf GoldPi /app/data/emailforwarder.db ← hier liegen die echten Daten

Im data/-Verzeichnis liegen aktuell:

emailforwarder.db        380.928   <- die ECHTEN Daten
emailforwarder.db-wal  4.124.152   <- ACHTUNG: groesser als die DB selbst!
emailforwarder.db-shm     32.768
mail-graveyard.db              0   <- Leiche
email-forwarder.db             0   <- Leiche

Der Schaden, wenn der Default je greift (jemand folgt der eigenen INSTALL.md, oder db_path fehlt in einer Config): SQLite legt klaglos eine frische, leere DB an. Konten weg, copied-Historie weg. Der Watcher sieht eine leere copied-Tabelle und kopiert jede Mail erneut in die Ziel-PostfaecherDubletten quer ueber alle ~20 echten dr-gold-Postfaecher, lautlos, ohne einen einzigen Fehler im Log.

Teil A — Die Daten umziehen (einmalige Ops-Aktion)

Ist-Zustand als Baseline (muss danach identisch sein; Jobs duerfen durch laufende Watch-/Deploy-Laeufe weiterzaehlen): accounts=19, copied=215, app_users=3, jobs=294 vor Ops, jobs=296 nach Deploy-Abnahme.

Reihenfolge ist wichtig — das WAL ist der gefaehrliche Teil:

APP=/mnt/DATA/Containers/Test-Container/Mail-Graveyard-Pod
D=$APP/data

# 1. BEIDE Container stoppen -> kein Schreiber mehr auf der DB
podman stop mail-graveyard mail-graveyard-watch

# 2. Backup, bevor irgendwas angefasst wird (inkl. WAL/SHM!)
cp -a $D/emailforwarder.db     $D/BACKUP-emailforwarder.db
cp -a $D/emailforwarder.db-wal $D/BACKUP-emailforwarder.db-wal

# 3. WAL in die Haupt-DB falten. OHNE DAS gehen 4 MB Daten verloren.
sqlite3 $D/emailforwarder.db "PRAGMA wal_checkpoint(TRUNCATE);"

# 4. Gegenpruefen, dass alles noch da ist
sqlite3 $D/emailforwarder.db "SELECT
  (SELECT COUNT(*) FROM accounts), (SELECT COUNT(*) FROM copied),
  (SELECT COUNT(*) FROM app_users), (SELECT COUNT(*) FROM jobs);"
#  -> MUSS accounts=19, copied=215, app_users=3 liefern. Wenn nicht: STOPP,
#     nichts weiter tun. jobs kann waehrend Watch/Deploy weiterwachsen.

# 5. Erst jetzt umbenennen (ueberschreibt die 0-Byte-Leiche)
mv -f $D/emailforwarder.db $D/mail-graveyard.db
rm -f $D/emailforwarder.db-wal $D/emailforwarder.db-shm $D/email-forwarder.db

# 6. Config umstellen
#    $APP/config.json:  "db_path": "/app/data/mail-graveyard.db"

Teil B — Die Ursache beseitigen (Code + Repo)

  1. deploy/goldpi-test-container/mail-graveyard-pod/config.json und config.json.example: db_path auf mail-graveyard.db — damit Doku, Deploy und Live endlich dasselbe sagen.
  2. Kein stilles Anlegen mehr. Das ist die eigentliche Wurzel: ConnectDB erzeugt heute klaglos eine leere DB, wenn die Datei fehlt. Bau eine Sicherung ein:
    • Wenn die DB-Datei nicht existiert, nur dann anlegen, wenn explizit --init-db uebergeben wurde. Sonst: laut scheitern mit DB %q existiert nicht — mit --init-db neu anlegen oder db_path pruefen und Exit ≠ 0.
    • Damit wird aus einem stillen Daten-GAU ein sofort sichtbarer Startfehler. Dasselbe Prinzip wie beim Watch-Fail-Fast: permanenter Konfigfehler muss schreien, nicht schweigen.

Abnahme

  1. Container wieder hoch, dann in der DB pruefen: accounts=19, copied=215, app_users=3, jobs=289identisch.
  2. Der entscheidende Test: Der erste Watcher-Lauf nach dem Umzug muss copied=0 melden (total=215 copied=0 errors=0). → Meldet er stattdessen copied=215, ist die Dedup-Historie verloren gegangen und er schreibt gerade Dubletten ins Ziel. Sofort stoppen und das Backup aus Schritt 2 zurueckspielen.
  3. Login in der Web-UI funktioniert weiter (die 3 Benutzer sind mitgezogen).
  4. go test ./... gruen.

Ich (Claude) verifiziere danach Punkt 13 unabhaengig auf GoldPi.