feat(backup): add standalone backup script, deprecate Go API route

This commit is contained in:
xiaowei 2026-06-10 10:19:55 +08:00
parent b237cc9aeb
commit c3db6ffe30
1 changed files with 40 additions and 114 deletions

View File

@ -1,130 +1,56 @@
#!/bin/bash
# ====== 织忆备份脚本 ======
# 备份到 server Giteahttp://192.168.123.11:3000
# 用法:./backup.sh [commit_message]
# 自动:每天 03:00见 cron 配置)
# 织忆每日备份脚本(由 cronjob 每天 04:00 调用)
# 直接执行备份,不走 Go HTTP API
set -e
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="${HOME}/.hermes/logs/backup.log"
API_KEY="zhiyi-dev-key-2026"
BACKUP_ROOT="/home/muc/backups/memoryweave"
DATA_DIR="/var/lib/memoryweave"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="$BACKUP_ROOT/$TIMESTAMP"
# 项目根目录backup.sh 同级)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
echo "[$TIMESTAMP] 织忆备份开始..."
# 备份临时目录
BACKUP_DIR="/tmp/zhiyi_backup_${DATE}"
CONFIG_DIR="/tmp/zhiyi_config_${DATE}"
# 1. 创建备份目录
mkdir -p "$BACKUP_DIR"
# 日志
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "===== 备份开始: ${DATE} ====="
# 1. 备份数据文件
log "[1/6] 备份数据文件..."
mkdir -p "${BACKUP_DIR}"
sudo rsync -a /var/lib/memoryweave/ "${BACKUP_DIR}/memoryweave/" --quiet
DATA_SIZE=$(du -sh "${BACKUP_DIR}" | cut -f1)
log " 数据备份完成: ${DATA_SIZE}"
# 2. 打包
log "[2/6] 打包数据..."
cd /tmp
tar -czf "zhiyi_backup_${DATE}.tar.gz" "zhiyi_backup_${DATE}/"
rm -rf "zhiyi_backup_${DATE}"
ARCHIVE_SIZE=$(du -sh "/tmp/zhiyi_backup_${DATE}.tar.gz" | cut -f1)
log " 打包完成: ${ARCHIVE_SIZE}"
# 3. 备份 Hermes 配置
log "[3/6] 备份 Hermes 配置..."
mkdir -p "${CONFIG_DIR}"
# 核心人格文件
rsync -a "${HOME}/.hermes/SOUL.md" "${CONFIG_DIR}/" 2>/dev/null || true
rsync -a "${HOME}/.hermes/AGENTS.md" "${CONFIG_DIR}/" 2>/dev/null || true
rsync -a "${HOME}/.hermes/MEMORY.md" "${CONFIG_DIR}/" 2>/dev/null || true
rsync -a "${HOME}/.hermes/USER.md" "${CONFIG_DIR}/" 2>/dev/null || true
# 配置文件
rsync -a "${HOME}/.hermes/config.yaml" "${CONFIG_DIR}/" 2>/dev/null || true
rsync -a "${HOME}/.hermes/.env" "${CONFIG_DIR}/" 2>/dev/null || true
rsync -a "${HOME}/.hermes/auth.json" "${CONFIG_DIR}/" 2>/dev/null || true
# skills / cron / kanban
[ -d "${HOME}/.hermes/skills" ] && rsync -a "${HOME}/.hermes/skills/" "${CONFIG_DIR}/skills/" --quiet
[ -d "${HOME}/.hermes/cron" ] && rsync -a "${HOME}/.hermes/cron/" "${CONFIG_DIR}/cron/" --quiet
[ -f "${HOME}/.hermes/kanban.db" ] && rsync -a "${HOME}/.hermes/kanban.db" "${CONFIG_DIR}/" 2>/dev/null || true
# memories / sessions可选较大
if [ -d "${HOME}/.hermes/memories" ] && [ "$(du -sm "${HOME}/.hermes/memories" 2>/dev/null | cut -f1)" -lt 500 ]; then
rsync -a "${HOME}/.hermes/memories/" "${CONFIG_DIR}/memories/" --quiet
fi
if [ -d "${HOME}/.hermes/sessions" ] && [ "$(du -sm "${HOME}/.hermes/sessions" 2>/dev/null | cut -f1)" -lt 200 ]; then
rsync -a "${HOME}/.hermes/sessions/" "${CONFIG_DIR}/sessions/" --quiet
# 2. SQLite graph.db 备份
echo "[$TIMESTAMP] 备份 graph.db..."
if ! sqlite3 "$DATA_DIR/graph.db" ".backup $BACKUP_DIR/graph.db"; then
echo "[$TIMESTAMP] ERROR: graph.db 备份失败"
exit 1
fi
CONFIG_SIZE=$(du -sh "${CONFIG_DIR}" | cut -f1)
log " 配置备份完成: ${CONFIG_SIZE}"
# 4. 推送到 Gitea
log "[4/6] 推送到 Gitea..."
# 确保 git 仓库存在
if [ ! -d "${PROJECT_ROOT}/.git" ]; then
log " WARM: ${PROJECT_ROOT} 不是 git 仓库,初始化..."
cd "${PROJECT_ROOT}"
git init
git remote add origin "http://192.168.123.11:3000/xiaoxue_admin/zhiyi-config.git" 2>/dev/null || true
# 3. SQLite memoryweave.db 备份
echo "[$TIMESTAMP] 备份 memoryweave.db..."
if ! sqlite3 "$DATA_DIR/memoryweave.db" ".backup $BACKUP_DIR/memoryweave.db"; then
echo "[$TIMESTAMP] ERROR: memoryweave.db 备份失败"
exit 1
fi
cd "${PROJECT_ROOT}"
# 4. Redis 异步保存
echo "[$TIMESTAMP] 触发 Redis BGSAVE..."
redis-cli BGSAVE 2>/dev/null || true
# 确保 data 目录存在
mkdir -p data
# 移动备份到 data 目录
mv "/tmp/zhiyi_backup_${DATE}.tar.gz" data/
# 把数据仓库也 clone/update
if [ ! -d "${PROJECT_ROOT}/zhiyi-backup" ]; then
git clone "http://192.168.123.11:3000/xiaoxue_admin/zhiyi-backup.git" "${PROJECT_ROOT}/zhiyi-backup" 2>/dev/null || {
# 如果仓库不存在,跳过数据备份
log " WARN: zhiyi-backup 仓库不存在或无法访问,跳过数据推送"
}
# 5. LanceDB 目录 tar 打包(最多等 300s
echo "[$TIMESTAMP] 打包 LanceDB 数据(可能需要 1-2 分钟)..."
if ! timeout 300 tar czf "$BACKUP_DIR/lance-data.tar.gz" \
-C "$DATA_DIR" episodes.lance memories.lance tombstones.lance; then
echo "[$TIMESTAMP] ERROR: LanceDB 打包超时或失败"
exit 1
fi
if [ -d "${PROJECT_ROOT}/zhiyi-backup" ]; then
cd "${PROJECT_ROOT}/zhiyi-backup"
# 移动 archive
if [ -f "${PROJECT_ROOT}/data/zhiyi_backup_${DATE}.tar.gz" ]; then
cp "${PROJECT_ROOT}/data/zhiyi_backup_${DATE}.tar.gz" .
git add "zhiyi_backup_${DATE}.tar.gz"
git commit -m "Backup data ${DATE}" 2>/dev/null || true
git push origin main 2>/dev/null || log " WARN: 数据推送失败(可能需要 token"
rm -f "zhiyi_backup_${DATE}.tar.gz"
# 6. 验证
echo "[$TIMESTAMP] 验证备份..."
for f in graph.db memoryweave.db lance-data.tar.gz; do
if [ ! -s "$BACKUP_DIR/$f" ]; then
echo "[$TIMESTAMP] ERROR: $f 为空或不存在"
exit 1
fi
cd "${PROJECT_ROOT}"
fi
done
# 推送配置
git add data/zhiyi_backup_${DATE}.tar.gz
git add config/ 2>/dev/null || true
git add -A
COMMIT_MSG="${1:-Backup ${DATE}}"
git commit -m "${COMMIT_MSG}" 2>/dev/null || log " WARN: 没有新内容需要提交"
git push origin main 2>/dev/null || log " WARN: 配置推送失败(可能需要 token"
# 5. 清理
log "[5/6] 清理临时文件..."
rm -rf "${BACKUP_DIR}" "${CONFIG_DIR}"
log " 清理完成"
# 6. 完成
log "[6/6] 备份完成"
log "===== 备份结束: ${DATE} ====="
echo ""
# 7. 打印结果
SIZE=$(du -sh "$BACKUP_DIR" | cut -f1)
echo "[$TIMESTAMP] 备份成功 | 路径: $BACKUP_DIR | 大小: $SIZE"
echo "[$TIMESTAMP] 织忆备份结果: OK | 路径: $BACKUP_DIR | 时间戳: $TIMESTAMP" > "$HOME/projects/memoryweave/backups/backup-$TIMESTAMP.log"