f8e870fd6a
远端 .backup 出的库 gzip 后可能 <50KB,原 >50k 检查把有效备份当'异常小'删了。 空 gzip 仅 ~20 字节,>1k 足以区分空/断流与有效备份。
55 lines
2.4 KiB
Bash
55 lines
2.4 KiB
Bash
#!/usr/bin/env bash
|
|
# backup-db.sh — pangolin1 控制面 SQLite 每日备份到 NAS(异地容灾,#26 / F2)。
|
|
#
|
|
# 经 ssh 在 pangolin1 上用 sqlite3 online `.backup` 取 WAL 一致快照(不阻塞服务、
|
|
# 不像裸 cp 那样可能拿到半写状态),远端先跑 PRAGMA integrity_check 确认没坏,再把
|
|
# 快照 gzip 流回 runner,落到 NAS 备份盘(默认 /volume1/docker/backups/pangolin,
|
|
# 该盘已挂进 runner 容器)。保留 30 天。异地 = 家里 NAS ≠ VPS 机房,构成容灾。
|
|
#
|
|
# 不在 pangolin1 上安装/常驻任何东西:调度在 Gitea Actions(backup.yml),每次经
|
|
# ssh 临时跑一次 sqlite3。需环境:DEPLOY_SSH_KEY(secret)。从 repo 根调用。
|
|
set -euo pipefail
|
|
|
|
# shellcheck source=scripts/ci/lib-ssh.sh
|
|
. scripts/ci/lib-ssh.sh
|
|
|
|
BACKUP_DIR="${BACKUP_DIR:-/volume1/docker/backups/pangolin}"
|
|
mkdir -p "$BACKUP_DIR"
|
|
|
|
# 时间戳文件名(bash 内建 strftime,免 $() 命令替换)。
|
|
printf -v TS '%(%Y%m%d_%H%M%S)T' -1
|
|
DEST="${BACKUP_DIR}/pangolin_${TS}.db.gz"
|
|
|
|
# setup_ssh 内部先注册 EXIT trap 清理临时私钥,再写 key/known_hosts,导出 $SSH。
|
|
setup_ssh
|
|
|
|
echo "==> backup-db: sqlite3 .backup pangolin1(${DEPLOY_HOST})-> ${DEST}"
|
|
# 远端单引号 heredoc:$BK/$$ 在 pangolin1 上展开。以 pangolin 用户(DB 属主)跑
|
|
# online .backup + integrity_check;校验通过才 cat 回流;临时文件用完即删。
|
|
# integrity_check 失败 → 远端非零退出 → 本地 pipefail 令整条命令失败 → set -e 中止。
|
|
$SSH "root@${DEPLOY_HOST}" 'bash -s' <<'ENDSSH' | gzip > "$DEST"
|
|
set -euo pipefail
|
|
BK="/tmp/pangolin-bk-$$.db"
|
|
trap 'rm -f "$BK"' EXIT
|
|
runuser -u pangolin -- sqlite3 "/var/lib/pangolin/pangolin.db" ".backup ${BK}"
|
|
if ! runuser -u pangolin -- sqlite3 "$BK" "PRAGMA integrity_check;" | grep -q '^ok$'; then
|
|
echo "backup-db(remote): integrity_check 失败" >&2
|
|
exit 1
|
|
fi
|
|
cat "$BK"
|
|
ENDSSH
|
|
|
|
# 本地二次校验:gzip 完好 + 非空 sanity。空 gzip 仅 ~20 字节;真备份(即便很小的库)
|
|
# gzip 后也远大于 1KB,故用 >1k 区分「空/断流」与「有效备份」(不用 50k:小库压缩后可能 <50k)。
|
|
gzip -t "$DEST"
|
|
if ! find "$DEST" -size +1k -print -quit | grep -q .; then
|
|
echo "==> backup-db: 备份异常小(<1k,疑似空/断流),中止" >&2
|
|
rm -f "$DEST"
|
|
exit 1
|
|
fi
|
|
|
|
# 保留最近 30 天。
|
|
find "$BACKUP_DIR" -name 'pangolin_*.db.gz' -mtime +30 -delete
|
|
|
|
echo "==> backup-db: 备份完成 ${DEST}"
|