Files
memory/backup.sh
2025-12-31 17:34:23 +08:00

106 lines
2.9 KiB
Bash
Raw Permalink 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.
#!/bin/bash
# Memory 数据库备份脚本
# 功能:备份 SQLite 数据库到 R2保留最近 7 天的备份
set -e
# ============ 配置区域 ============
# R2 配置
R2_ACCOUNT_ID="ebf33b5ee4eb26f32af0c6e06102e000"
R2_ACCESS_KEY_ID="8acbc8a9386d60d0e8dac6bd8165c618"
R2_ACCESS_KEY_SECRET="72935e23b5b4be8fda99008e75285e8ac778f8926656c42780b25785bb149443"
R2_BUCKET_NAME="memory"
R2_BACKUP_PATH="memory-backup"
# 数据库路径
DB_PATH="/amos/memory/data/memory.db"
# 备份保留天数
KEEP_DAYS=7
# 日志文件
LOG_FILE="/var/log/memory-backup.log"
# ============ 函数定义 ============
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
# 上传备份到 R2
upload_backup() {
local backup_file=$1
local remote_name=$2
AWS_ACCESS_KEY_ID=$R2_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$R2_ACCESS_KEY_SECRET \
aws s3 cp "$backup_file" "s3://${R2_BUCKET_NAME}/${R2_BACKUP_PATH}/${remote_name}" \
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com"
}
# 清理旧备份,只保留最近 N 天
cleanup_old_backups() {
log "清理旧备份..."
# 列出所有备份文件,按时间倒序排列
local backup_list=$(AWS_ACCESS_KEY_ID=$R2_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$R2_ACCESS_KEY_SECRET \
aws s3 ls "s3://${R2_BUCKET_NAME}/${R2_BACKUP_PATH}/" \
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" \
| grep "memory-.*\.db" \
| sort -r \
| awk '{print $4}')
# 跳过前 N 个(最新的),删除其余的
local count=0
for backup in $backup_list; do
count=$((count + 1))
if [ $count -gt $KEEP_DAYS ]; then
log " 删除: $backup"
AWS_ACCESS_KEY_ID=$R2_ACCESS_KEY_ID \
AWS_SECRET_ACCESS_KEY=$R2_ACCESS_KEY_SECRET \
aws s3 rm "s3://${R2_BUCKET_NAME}/${R2_BACKUP_PATH}/${backup}" \
--endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com"
fi
done
if [ $count -le $KEEP_DAYS ]; then
log " 无需清理,当前共 ${count} 个备份"
else
log " 已清理 $((count - KEEP_DAYS)) 个旧备份"
fi
}
# ============ 主流程 ============
log "========== 开始备份 =========="
# 检查数据库文件是否存在
if [ ! -f "$DB_PATH" ]; then
log "❌ 数据库文件不存在: $DB_PATH"
exit 1
fi
# 生成备份文件名(带日期)
DATE=$(date '+%Y-%m-%d')
BACKUP_NAME="memory-${DATE}.db"
TEMP_BACKUP="/tmp/${BACKUP_NAME}"
# 使用 sqlite3 的 .backup 命令进行热备份(避免数据损坏)
log "备份数据库..."
sqlite3 "$DB_PATH" ".backup '$TEMP_BACKUP'"
# 上传到 R2
log "上传到 R2..."
upload_backup "$TEMP_BACKUP" "$BACKUP_NAME"
# 清理临时文件
rm -f "$TEMP_BACKUP"
# 清理旧备份
cleanup_old_backups
log "✅ 备份完成: ${BACKUP_NAME}"
log "========== 备份结束 =========="