#!/bin/bash # 考陪练系统数据库自动备份脚本 # 作者: AI Assistant # 日期: 2025-09-23 set -e # 遇到错误立即退出 # 配置变量 BACKUP_DIR="/root/aiedu/kaopeilian-backend/backups" CONTAINER_NAME="kaopeilian_mysql" DB_NAME="kaopeilian" DB_USER="root" DB_PASSWORD="Kaopeilian2025!@#" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="${BACKUP_DIR}/kaopeilian_backup_${DATE}.sql" LOG_FILE="${BACKUP_DIR}/backup.log" RETENTION_DAYS=30 # 保留30天的备份 # 创建备份目录 mkdir -p "${BACKUP_DIR}" # 日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${LOG_FILE}" } # 检查Docker容器是否运行 check_container() { if ! docker ps | grep -q "${CONTAINER_NAME}"; then log "ERROR: MySQL容器 ${CONTAINER_NAME} 未运行" exit 1 fi } # 执行数据库备份 backup_database() { log "开始备份Docker容器中的数据库 ${DB_NAME}..." # 检查容器是否运行 if ! docker ps | grep -q "${CONTAINER_NAME}"; then log "ERROR: MySQL容器 ${CONTAINER_NAME} 未运行" return 1 fi # 使用docker exec执行mysqldump,将输出重定向到宿主机文件 if docker exec "${CONTAINER_NAME}" mysqldump \ -u"${DB_USER}" \ -p"${DB_PASSWORD}" \ --single-transaction \ --routines \ --triggers \ --events \ --hex-blob \ --default-character-set=utf8mb4 \ --lock-tables=false \ --add-drop-database \ --create-options \ "${DB_NAME}" > "${BACKUP_FILE}" 2>/dev/null; then # 检查备份文件大小 if [ -f "${BACKUP_FILE}" ] && [ -s "${BACKUP_FILE}" ]; then BACKUP_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1) log "备份完成: ${BACKUP_FILE} (大小: ${BACKUP_SIZE})" # 验证备份文件内容(检查是否包含CREATE DATABASE语句) if grep -q "CREATE DATABASE" "${BACKUP_FILE}"; then log "备份文件验证成功" return 0 else log "WARNING: 备份文件可能不完整" return 0 # 仍然算作成功,但记录警告 fi else log "ERROR: 备份文件为空或不存在" rm -f "${BACKUP_FILE}" return 1 fi else log "ERROR: 数据库备份失败" return 1 fi } # 压缩备份文件 compress_backup() { if [ -f "${BACKUP_FILE}" ]; then log "压缩备份文件..." gzip "${BACKUP_FILE}" COMPRESSED_FILE="${BACKUP_FILE}.gz" COMPRESSED_SIZE=$(du -h "${COMPRESSED_FILE}" | cut -f1) log "压缩完成: ${COMPRESSED_FILE} (大小: ${COMPRESSED_SIZE})" fi } # 清理过期备份 cleanup_old_backups() { log "清理 ${RETENTION_DAYS} 天前的备份文件..." find "${BACKUP_DIR}" -name "kaopeilian_backup_*.sql.gz" -mtime +${RETENTION_DAYS} -delete find "${BACKUP_DIR}" -name "kaopeilian_backup_*.sql" -mtime +${RETENTION_DAYS} -delete log "过期备份清理完成" } # 发送备份状态通知(可选) send_notification() { local status=$1 local message=$2 # 这里可以集成邮件、钉钉、微信等通知方式 log "通知: ${status} - ${message}" # 示例:写入状态文件供监控系统读取 echo "{\"timestamp\":\"$(date -Iseconds)\",\"status\":\"${status}\",\"message\":\"${message}\"}" > "${BACKUP_DIR}/backup_status.json" } # 主函数 main() { log "========== 数据库备份开始 ==========" # 检查容器状态 check_container # 执行备份 if backup_database; then # 压缩备份 compress_backup # 清理过期备份 cleanup_old_backups # 发送成功通知 send_notification "SUCCESS" "数据库备份成功完成" log "========== 数据库备份完成 ==========" exit 0 else # 发送失败通知 send_notification "FAILED" "数据库备份失败" log "========== 数据库备份失败 ==========" exit 1 fi } # 执行主函数 main "$@"