Files
Harlekin e0b03ea336
Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
Gedankenstriche durch Bindestriche ersetzt
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die
README; an keiner Stelle Bedeutung, nur Zeichensetzung.
2026-09-04 08:54:52 +02:00

76 lines
2.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Spielt eine Sicherung in eine Wegwerf-Datenbank ein und prüft, ob alles
# angekommen ist. Ein ungetestetes Backup ist keins - siehe docs/11-betrieb.md.
#
# scripts/restore-test.sh [container] [quelldatenbank]
#
# Legt `<db>_restore_test` an, spielt einen frischen Dump hinein, vergleicht
# Zeilenzahlen, Regeln und Trigger, und räumt danach auf.
set -euo pipefail
CONTAINER="${1:-afis-dev-db}"
QUELLE="${2:-afis}"
ZIEL="${QUELLE}_restore_test"
NUTZER="afis"
rot() { printf '\033[31m%s\033[0m\n' "$*"; }
gruen() { printf '\033[32m%s\033[0m\n' "$*"; }
info() { printf ' %s\n' "$*"; }
psql_in() { docker exec "$CONTAINER" psql -U "$NUTZER" -d "$1" -tA -c "$2"; }
docker exec "$CONTAINER" pg_isready -U "$NUTZER" -d "$QUELLE" >/dev/null 2>&1 \
|| { rot "Container $CONTAINER antwortet nicht."; exit 1; }
echo "Wiederherstellung prüfen: ${QUELLE} -> ${ZIEL}"
info "Dump erzeugen"
docker exec "$CONTAINER" pg_dump -U "$NUTZER" -d "$QUELLE" -Fc -f /tmp/restore-test.dump
info "Zieldatenbank neu anlegen"
docker exec "$CONTAINER" psql -U "$NUTZER" -d postgres -q \
-c "DROP DATABASE IF EXISTS \"${ZIEL}\";" -c "CREATE DATABASE \"${ZIEL}\";"
info "Einspielen"
# pg_restore meldet auf einer frischen Datenbank Warnungen zu Besitzrechten.
# Die sind erwartbar; entscheidend ist der Vergleich danach.
docker exec "$CONTAINER" pg_restore -U "$NUTZER" -d "$ZIEL" --no-owner \
/tmp/restore-test.dump >/dev/null 2>&1 || true
FEHLER=0
info "Zeilen vergleichen"
for TABELLE in Case CaseEntry Document PersonnelFile AuditLog ChatMessage SearchIndex; do
A=$(psql_in "$QUELLE" "SELECT count(*) FROM \"$TABELLE\";" 2>/dev/null || echo "-")
B=$(psql_in "$ZIEL" "SELECT count(*) FROM \"$TABELLE\";" 2>/dev/null || echo "-")
if [ "$A" = "$B" ]; then
info "$TABELLE: $A"
else
rot " $TABELLE: Quelle $A, Wiederherstellung $B"
FEHLER=1
fi
done
# Ohne Regeln und Trigger wäre die Wiederherstellung eine Datenbank ohne die
# harten Zusicherungen: löschbare Verlaufseinträge, kein Suchindex.
REGELN=$(psql_in "$ZIEL" "SELECT count(*) FROM pg_rules WHERE schemaname='public';")
TRIGGER=$(psql_in "$ZIEL" "SELECT count(*) FROM pg_trigger WHERE NOT tgisinternal;")
info "Regeln: ${REGELN}, Trigger: ${TRIGGER}"
[ "$REGELN" -ge 5 ] || { rot " Zu wenige Regeln: die Anhängigkeit fehlt."; FEHLER=1; }
[ "$TRIGGER" -ge 5 ] || { rot " Zu wenige Trigger: Suchindex oder Wächter fehlen."; FEHLER=1; }
# Stichprobe auf die wichtigste Regel überhaupt.
psql_in "$ZIEL" "SELECT 1 FROM pg_rules WHERE rulename='entry_no_delete';" | grep -q 1 \
|| { rot " entry_no_delete fehlt: Verlaufseinträge wären löschbar."; FEHLER=1; }
info "Aufräumen"
docker exec "$CONTAINER" psql -U "$NUTZER" -d postgres -q -c "DROP DATABASE IF EXISTS \"${ZIEL}\";"
docker exec "$CONTAINER" rm -f /tmp/restore-test.dump
if [ "$FEHLER" = "0" ]; then
gruen "Wiederherstellung geprüft: alles angekommen."
else
rot "Wiederherstellung unvollständig."
exit 1
fi