#!/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 "========== 备份结束 =========="