#!/usr/bin/env bash # # Sichert die zentrale Kontroll-Datenbank und jede Workspace-Datei einzeln. # # sqlite3 .backup ist dafür gebaut, auch während der Server im WAL-Modus # schreibt (siehe AUSBAUSTUFEN.md 4.4 und README.md "Datensicherung") — eine # einfache Dateikopie wäre hier riskant. # # Jede Sicherung landet in einem eigenen, zeitgestempelten Ordner. Da jeder # Workspace seine eigene Datei ist, lässt sich später auch nur eine einzelne # Abteilung gezielt wiederherstellen, ohne die übrigen anzufassen. # # ── Aufruf ─────────────────────────────────────────────────────────────────── # # scripts/backup.sh [Datenverzeichnis] [Sicherungsverzeichnis] # # Beide Pfade lassen sich auch über die Umgebungsvariablen DATA_DIR und # BACKUP_DIR setzen (Vorgaben: "data" und "backups") — praktisch für einen # Cronjob, der ohnehin feste Pfade mitgibt. # # ── Beispiel für Cron ──────────────────────────────────────────────────────── # # Täglich um 3 Uhr, mit 14 Tagen Aufbewahrung: # # 0 3 * * * DATA_DIR=/srv/munin/data BACKUP_DIR=/srv/backups RETENTION_DAYS=14 \ # /srv/munin/scripts/backup.sh >> /var/log/munin-backup.log 2>&1 # # Ohne RETENTION_DAYS bleibt jede Sicherung liegen — lieber zu viel als # versehentlich eine noch gebrauchte Sicherung verlieren. # # ── Wiederherstellen ───────────────────────────────────────────────────────── # # Server stoppen, die gewünschte .db-Datei aus einem Sicherungsordner an ihren # Platz unter DATA_DIR zurückkopieren, Server wieder starten. Für einen # einzelnen Workspace reicht dessen Datei unter workspaces/ — die # Kontroll-Datenbank bleibt davon unberührt. set -euo pipefail datenverzeichnis="${1:-${DATA_DIR:-data}}" sicherungsverzeichnis="${2:-${BACKUP_DIR:-backups}}" stempel="$(date +%Y-%m-%dT%H-%M-%S)" ziel="$sicherungsverzeichnis/$stempel" if ! command -v sqlite3 >/dev/null 2>&1; then echo "sqlite3 ist nicht installiert — ohne dieses Werkzeug keine sichere Sicherung im laufenden Betrieb." >&2 exit 1 fi if [ ! -d "$datenverzeichnis" ]; then echo "Datenverzeichnis $datenverzeichnis existiert nicht." >&2 exit 1 fi mkdir -p "$ziel/workspaces" sichern() { sqlite3 "$1" ".backup '$2'" } if [ -f "$datenverzeichnis/control.db" ]; then sichern "$datenverzeichnis/control.db" "$ziel/control.db" echo "control.db gesichert" else echo "Warnung: $datenverzeichnis/control.db nicht gefunden — übersprungen." >&2 fi anzahl=0 for datei in "$datenverzeichnis"/workspaces/*.db; do [ -e "$datei" ] || continue # kein Workspace vorhanden (glob lief leer) sichern "$datei" "$ziel/workspaces/$(basename "$datei")" anzahl=$((anzahl + 1)) done echo "$anzahl Workspace-Datei(en) gesichert nach $ziel" # Alte Sicherungen aufräumen, falls eine Aufbewahrungsfrist gesetzt ist. if [ -n "${RETENTION_DAYS:-}" ]; then find "$sicherungsverzeichnis" -mindepth 1 -maxdepth 1 -type d -mtime "+$RETENTION_DAYS" -print -exec rm -rf {} \; fi