#!/bin/bash # ==================================================== # 工作日志服务平台 - 数据库备份脚本 # ==================================================== # 说明: # 1. 支持全量备份和增量备份 # 2. 自动压缩备份文件 # 3. 自动清理过期备份 # 4. 建议配置到 crontab 定时执行 # ==================================================== # ==================== 配置参数 ==================== # 数据库配置 DB_HOST="localhost" DB_PORT="3306" DB_NAME="worklog" DB_USER="worklog" DB_PASSWORD="Wlog@123" # 备份目录配置 BACKUP_ROOT="/backup/mysql" BACKUP_DIR="${BACKUP_ROOT}/${DB_NAME}" FULL_BACKUP_DIR="${BACKUP_DIR}/full" INCR_BACKUP_DIR="${BACKUP_DIR}/incr" # 保留策略(天数) FULL_KEEP_DAYS=28 # 全量备份保留 4 周 INCR_KEEP_DAYS=7 # 增量备份保留 7 天 # 日志文件 LOG_FILE="${BACKUP_DIR}/backup.log" # ==================== 初始化 ==================== # 创建备份目录 mkdir -p "${FULL_BACKUP_DIR}" mkdir -p "${INCR_BACKUP_DIR}" mkdir -p "$(dirname ${LOG_FILE})" # 日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${LOG_FILE}" } # ==================== 全量备份 ==================== full_backup() { log "========== 开始全量备份 ==========" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="${FULL_BACKUP_DIR}/full_${DATE}.sql" log "备份文件: ${BACKUP_FILE}" # 执行备份 mysqldump \ -h"${DB_HOST}" \ -P"${DB_PORT}" \ -u"${DB_USER}" \ -p"${DB_PASSWORD}" \ --single-transaction \ --routines \ --triggers \ --events \ --hex-blob \ --default-character-set=utf8mb4 \ "${DB_NAME}" > "${BACKUP_FILE}" 2>> "${LOG_FILE}" if [ $? -eq 0 ]; then log "数据库备份成功" # 压缩备份文件 log "开始压缩备份文件..." gzip "${BACKUP_FILE}" if [ $? -eq 0 ]; then BACKUP_SIZE=$(du -h "${BACKUP_FILE}.gz" | awk '{print $1}') log "压缩完成,文件大小: ${BACKUP_SIZE}" log "备份文件路径: ${BACKUP_FILE}.gz" else log "ERROR: 压缩失败" return 1 fi else log "ERROR: 数据库备份失败" return 1 fi log "========== 全量备份完成 ==========" return 0 } # ==================== 增量备份 ==================== # 注意:MySQL 增量备份需要启用 binlog # 本脚本暂不实现增量备份,可根据需要扩展 incr_backup() { log "========== 增量备份 ==========" log "INFO: 增量备份功能暂未实现,建议每日执行全量备份" log "如需增量备份,请启用 MySQL binlog 并配置 mysqlbinlog 工具" } # ==================== 清理过期备份 ==================== cleanup_old_backups() { log "========== 开始清理过期备份 ==========" # 清理过期全量备份 log "清理 ${FULL_KEEP_DAYS} 天前的全量备份..." find "${FULL_BACKUP_DIR}" -name "full_*.sql.gz" -type f -mtime +${FULL_KEEP_DAYS} -delete FULL_COUNT=$(find "${FULL_BACKUP_DIR}" -name "full_*.sql.gz" -type f | wc -l) log "当前保留全量备份文件数: ${FULL_COUNT}" # 清理过期增量备份 log "清理 ${INCR_KEEP_DAYS} 天前的增量备份..." find "${INCR_BACKUP_DIR}" -name "incr_*.sql.gz" -type f -mtime +${INCR_KEEP_DAYS} -delete INCR_COUNT=$(find "${INCR_BACKUP_DIR}" -name "incr_*.sql.gz" -type f | wc -l) log "当前保留增量备份文件数: ${INCR_COUNT}" log "========== 清理完成 ==========" } # ==================== 恢复脚本 ==================== restore_backup() { BACKUP_FILE=$1 if [ -z "${BACKUP_FILE}" ]; then log "ERROR: 请指定要恢复的备份文件" echo "用法: $0 restore " exit 1 fi if [ ! -f "${BACKUP_FILE}" ]; then log "ERROR: 备份文件不存在: ${BACKUP_FILE}" exit 1 fi log "========== 开始恢复数据库 ==========" log "WARNING: 此操作将覆盖当前数据库,请确认!" read -p "确认恢复? (yes/no): " CONFIRM if [ "${CONFIRM}" != "yes" ]; then log "取消恢复操作" exit 0 fi log "正在恢复备份文件: ${BACKUP_FILE}" # 解压并恢复 gunzip -c "${BACKUP_FILE}" | mysql \ -h"${DB_HOST}" \ -P"${DB_PORT}" \ -u"${DB_USER}" \ -p"${DB_PASSWORD}" \ "${DB_NAME}" 2>> "${LOG_FILE}" if [ $? -eq 0 ]; then log "数据库恢复成功" else log "ERROR: 数据库恢复失败" exit 1 fi log "========== 恢复完成 ==========" } # ==================== 主函数 ==================== main() { case "$1" in full) full_backup cleanup_old_backups ;; incr) incr_backup cleanup_old_backups ;; restore) restore_backup "$2" ;; cleanup) cleanup_old_backups ;; *) echo "用法: $0 {full|incr|restore|cleanup}" echo "" echo "命令说明:" echo " full - 执行全量备份" echo " incr - 执行增量备份(暂未实现)" echo " restore - 恢复备份(需指定备份文件)" echo " cleanup - 清理过期备份" echo "" echo "示例:" echo " $0 full # 全量备份" echo " $0 restore /backup/mysql/worklog/full/full_20260224_020000.sql.gz" exit 1 ;; esac } # 执行主函数 main "$@"