fix: 备份与恢复脚本深度修复

backup-db.sh:
- 新增备份后 SQLite 文件有效性验证(scp 传输后检查)

restore-db.sh (云端恢复):
- 修复:验证用 docker cp + docker exec sqlite3,不再依赖宿主机 sqlite3
- 修复:先停止容器再替换数据库,防止写入冲突
- 修复:替换后删除 WAL/SHM 残留文件,防止旧日志与新库不匹配损坏
This commit is contained in:
aiyimickey 2026-05-15 16:24:41 +08:00
parent d65583f6df
commit 7c213873bb
2 changed files with 28 additions and 8 deletions

View File

@ -29,6 +29,16 @@ log "复制到本地..."
scp "txjp:/tmp/db-backup/assets-${TIMESTAMP}.db" "${LOCAL_DIR}/"
scp "txjp:/tmp/db-backup/issue-${TIMESTAMP}.db" "${LOCAL_DIR}/"
# 验证备份文件为有效 SQLite 数据库
log "验证备份完整性..."
for f in "${LOCAL_DIR}/assets-${TIMESTAMP}.db" "${LOCAL_DIR}/issue-${TIMESTAMP}.db"; do
if ! sqlite3 "$f" "SELECT count(*) FROM sqlite_master" > /dev/null 2>&1; then
echo "[错误] 备份文件无效或损坏: $f"
exit 1
fi
done
log "备份文件验证通过"
# 清理云端临时文件
ssh txjp "rm -rf /tmp/db-backup"

View File

@ -155,8 +155,10 @@ restore_cloud() {
exit 1
fi
# 2. 验证备份文件
if ! ssh txjp "sqlite3 ${BACKUP_PATH} 'SELECT count(*) FROM sqlite_master' > /dev/null 2>&1"; then
# 2. 验证备份文件(通过临时容器,避免依赖宿主机 sqlite3
if ! ssh txjp "docker cp ${BACKUP_PATH} ${CONTAINER}:/tmp/restore-check.db 2>/dev/null && \
docker exec ${CONTAINER} sqlite3 /tmp/restore-check.db 'SELECT count(*) FROM sqlite_master' > /dev/null 2>&1 && \
docker exec ${CONTAINER} rm /tmp/restore-check.db"; then
echo "[错误] 备份文件不是有效的 SQLite 数据库"
exit 1
fi
@ -191,21 +193,29 @@ restore_cloud() {
exit 0
fi
# 5. 云端安全备份当前数据库
# 5. 停止容器(确保数据库不被写入,安全替换)
echo "[操作] 停止容器 ${CONTAINER}..."
ssh txjp "cd /root/docker/${PROJECT_DIR} && docker compose stop ${CONTAINER}"
# 6. 备份当前数据库(容器已停止,安全复制)
local SAFE_NAME="before-restore-$(date +%Y%m%d_%H%M%S).db"
echo "[操作] 备份云端当前数据库..."
ssh txjp "docker cp ${CONTAINER}:${DB_PATH_IN_CONTAINER} /root/docker/db-backups/${SAFE_NAME}"
echo "[备份] 当前数据库已保存至云端: /root/docker/db-backups/${SAFE_NAME}"
# 6. 复制备份文件到容器
# 7. 替换数据库
echo "[操作] 复制备份文件到容器..."
ssh txjp "docker cp ${BACKUP_PATH} ${CONTAINER}:${DB_PATH_IN_CONTAINER}"
# 7. 重启容器
echo "[操作] 重启容器 ${CONTAINER}..."
ssh txjp "cd /root/docker/${PROJECT_DIR} && docker compose restart ${CONTAINER}"
# 8. 删除残留 WAL/SHM 文件,防止旧日志与新数据库不匹配导致损坏
echo "[操作] 清理残留 WAL/SHM 文件..."
ssh txjp "docker exec ${CONTAINER} rm -f ${DB_PATH_IN_CONTAINER}-shm ${DB_PATH_IN_CONTAINER}-wal" 2>/dev/null || true
# 8. 验证
# 9. 启动容器
echo "[操作] 启动容器 ${CONTAINER}..."
ssh txjp "cd /root/docker/${PROJECT_DIR} && docker compose start ${CONTAINER}"
# 10. 验证
sleep 3
echo ""
echo "[验证] 恢复后数据:"