Files
caiwuzongzhang/deploy/backup.sh
T

53 lines
2.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 在线热备:不停服备份 SQLite(backup API 保证一致性)+ files/ 原始文件目录。
# 用法:./backup.sh [备份根目录](默认 ../backups
# 保留策略:日备保留 30 天,每月 1 号的首份备份额外保留 12 个月(monthly/)。
# 建议宿主机 cron15 2 * * * /path/to/deploy/backup.sh >> /path/to/deploy/backup.log 2>&1
# 官方环境建议至少将 monthly/ 同步一份到异机/异盘。
set -euo pipefail
ROOT="$(cd "$(dirname "$0")" && pwd)"
DEST="${1:-$ROOT/../backups}"
CONTAINER="${CONTAINER:-caiwuzongzhang-app}"
STAMP="$(date +%Y%m%d-%H%M%S)"
DAY_DIR="$DEST/daily"
MONTH_DIR="$DEST/monthly"
mkdir -p "$DAY_DIR" "$MONTH_DIR"
# 1) SQLite 在线热备(容器内 python sqlite3 backup API,主库可继续写入)
docker exec "$CONTAINER" python - <<'PY'
import os, sqlite3
src = sqlite3.connect(os.environ.get("APP_DB_PATH", "/app/data/app.db"))
dst = sqlite3.connect("/tmp/app.db.backup")
src.backup(dst)
dst.close(); src.close()
print("hot-backup ok")
PY
docker cp "$CONTAINER:/tmp/app.db.backup" "$DAY_DIR/app.db.$STAMP"
docker exec "$CONTAINER" rm -f /tmp/app.db.backup
# 2) 原始文件目录打包(银行原始证据,只读复制,绝不改动)
tar -C "$ROOT/.." -czf "$DAY_DIR/files.$STAMP.tar.gz" data/files
# 3) 完整性自检:PRAGMA integrity_check + 关键计数
docker run --rm -v "$DAY_DIR/app.db.$STAMP:/check/app.db:ro" python:3.12-slim-bookworm \
python -c "
import sqlite3
c = sqlite3.connect('/check/app.db')
print('integrity:', c.execute('PRAGMA integrity_check').fetchone()[0])
for t in ('source_rows', 'transfer_match_decisions', 'period_close_runs', 'audit_log'):
try:
print(t, c.execute(f'SELECT COUNT(*) FROM {t}').fetchone()[0])
except sqlite3.OperationalError:
print(t, 'n/a')
"
# 4) 保留策略:日备 >30 天删除;每月 1 号留档 monthly/
find "$DAY_DIR" -name 'app.db.*' -mtime +30 -delete
find "$DAY_DIR" -name 'files.*.tar.gz' -mtime +30 -delete
if [ "$(date +%d)" = "01" ]; then
cp "$DAY_DIR/app.db.$STAMP" "$MONTH_DIR/app.db.$STAMP"
cp "$DAY_DIR/files.$STAMP.tar.gz" "$MONTH_DIR/files.$STAMP.tar.gz"
find "$MONTH_DIR" -mtime +365 -delete
fi
echo "backup complete: $DAY_DIR/app.db.$STAMP"