Files
Vladimir Buzalka 2bdac59676 notebookvb
2026-06-14 12:07:35 +02:00

93 lines
3.5 KiB
Bash

#!/bin/bash
# Denni obnova zrcadla Medicus DB z nejnovejsi gbak zalohy do Firebird kontejneru
# + GFS retence zaloh.
#
# Zalohy se v adresari HROMADI a nejnovejsi se muze prave PRENASET pres rsync. Proto:
# - vybira nejnovejsi MEDICUS_*.zip podle nazvu (RRMMDD_HHMM -> lexikalne = chronologicky)
# - pamatuje si posledni uspesne restorovanou (last_restored.txt) -> neni-li nic novejsiho, konci
# - ceka, az velikost prestane rust (probiha-li rsync), a overi integritu (unzip -t),
# teprve pak restoruje -> nikdy nezpracuje nekompletni prenos
# - marker se zapise az PO uspesnem restoru
# - na konci spusti GFS retenci zaloh (prune_backups.sh)
set -euo pipefail
NAME=firebird-medicus
APPDATA=/mnt/user/appdata/firebird-medicus
DATA="$APPDATA/fb/data"
WORK="$APPDATA/work"
BACKUP_DIR=/mnt/user/OrdinaceSynology/MedicusBackup
GBAK=/usr/local/firebird/bin/gbak
PASS=masterkey
BASE_DIR=/mnt/user/Scripts/MedicusFirebird
STATE="$BASE_DIR/last_restored.txt"
LOG="$BASE_DIR/restore.log"
# Retence: ostra (maze dle GFS 30d/8t/12m). Pro testovaci beh prepnout na 1 (jen vypis).
RETENTION_DRYRUN="${RETENTION_DRYRUN:-0}"
exec >>"$LOG" 2>&1
exec 9>"$BASE_DIR/.restore.lock"
flock -n 9 || { echo "$(date '+%F %T') jiny restore uz bezi -> koncim."; exit 0; }
echo "===== $(date '+%F %T') restore start ====="
mkdir -p "$WORK" "$DATA"
# --- 1) nejnovejsi zaloha podle nazvu ---
ZIP=$(ls -1 "$BACKUP_DIR"/MEDICUS_*.zip 2>/dev/null | sort | tail -1 || true)
if [ -z "${ZIP:-}" ]; then echo "CHYBA: zadna zaloha v $BACKUP_DIR"; exit 1; fi
ZIP_BASE=$(basename "$ZIP")
LAST=$(cat "$STATE" 2>/dev/null || echo "")
echo "Nejnovejsi: $ZIP_BASE | posledni restorovana: ${LAST:-<zadna>}"
# --- 2) uz restorovana? ---
if [ "$ZIP_BASE" = "$LAST" ]; then
echo "Nic noveho -> restore preskocen."
else
# --- 3) pockej na dokonceni prenosu (velikost se ustali) ---
prev=-1; stable=0
for i in $(seq 1 80); do # max ~20 min cekani na rsync
cur=$(stat -c %s "$ZIP" 2>/dev/null || echo 0)
if [ "$cur" = "$prev" ] && [ "$cur" -gt 0 ]; then stable=1; break; fi
echo " ...$ZIP_BASE = $cur B, cekam na ustaleni"
prev=$cur; sleep 15
done
[ "$stable" = "1" ] || { echo "CHYBA: $ZIP_BASE se stale meni -> koncim (priste)."; exit 1; }
# --- 4) integrita (nekompletni/poskozeny zip neprojde) ---
echo "unzip -t ..."
unzip -tqq "$ZIP" || { echo "CHYBA: $ZIP_BASE neprosel unzip -t -> koncim."; exit 1; }
# --- 5) rozbaleni .fbk ---
rm -f "$WORK"/*.fbk
unzip -o "$ZIP" -d "$WORK" >/dev/null
FBK=$(ls -1t "$WORK"/*.fbk | head -1)
FBK_BASE=$(basename "$FBK")
echo "FBK: $FBK_BASE ($(du -h "$FBK" | cut -f1))"
# --- 6) restore pres bezici server do noveho souboru ---
docker start "$NAME" >/dev/null 2>&1 || true
sleep 8
echo "gbak restore -> medicus_new.fdb ..."
docker exec "$NAME" rm -f /firebird/data/medicus_new.fdb
docker exec "$NAME" "$GBAK" -r -p 8192 -user SYSDBA -password "$PASS" \
"/work/$FBK_BASE" "localhost:/firebird/data/medicus_new.fdb"
# --- 7) atomicky swap + restart ---
echo "swap + restart ..."
docker stop "$NAME" >/dev/null
mv -f "$DATA/medicus_new.fdb" "$DATA/medicus.fdb"
docker start "$NAME" >/dev/null
sleep 8
rm -f "$WORK"/*.fbk
# --- 8) marker az po uspechu ---
echo "$ZIP_BASE" > "$STATE"
echo "restore OK: $ZIP_BASE"
fi
# --- 9) GFS retence zaloh ---
echo "--- retence zaloh (DRY_RUN=$RETENTION_DRYRUN) ---"
DRY_RUN="$RETENTION_DRYRUN" "$BASE_DIR/prune_backups.sh" || echo "VAROVANI: prune_backups.sh selhal"
echo "===== $(date '+%F %T') hotovo ====="