自动备份脚本 mysql_hourly_backup.sh
自动备份脚本 mysql_hourly_backup.sh
#!/bin/bash# MySQL Docker 每小时自动备份脚本
# 作者: Auto Backup Script
# 描述: 每小时自动备份MySQL数据库到指定目录,保留24小时备份set -e # 遇到错误立即退出# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color# 配置变量
MYSQL_CONTAINER="mysql"
MYSQL_USER="root"
MYSQL_PASSWORD="root123"
BACKUP_DIR="/opt/mysql/backups"
LOG_FILE="/var/log/mysql_backup.log"
RETENTION_HOURS=24 # 保留24小时备份(24个备份文件)# 日志函数
log_info() {echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] [INFO]${NC} $1" | tee -a "$LOG_FILE"
}log_success() {echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] [SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
}log_warning() {echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] [WARNING]${NC} $1" | tee -a "$LOG_FILE"
}log_error() {echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR]${NC} $1" | tee -a "$LOG_FILE"
}# 检查依赖
check_dependencies() {if ! command -v docker &> /dev/null; thenlog_error "Docker未安装"exit 1fiif ! docker ps | grep -q "$MYSQL_CONTAINER"; thenlog_error "MySQL容器未运行: $MYSQL_CONTAINER"exit 1fi
}# 创建备份目录
create_backup_dir() {if [ ! -d "$BACKUP_DIR" ]; thensudo mkdir -p "$BACKUP_DIR"sudo chmod 755 "$BACKUP_DIR"log_info "创建备份目录: $BACKUP_DIR"fiif [ ! -f "$LOG_FILE" ]; thensudo touch "$LOG_FILE"sudo chmod 644 "$LOG_FILE"fi
}# 执行数据库备份
perform_backup() {local timestamp=$(date '+%Y%m%d_%H%M%S')local backup_file="${BACKUP_DIR}/backup_${timestamp}.sql.gz"local temp_file="${BACKUP_DIR}/backup_${timestamp}.sql"log_info "开始备份数据库..."# 执行备份if docker exec "$MYSQL_CONTAINER" mysqldump \-u"$MYSQL_USER" \-p"$MYSQL_PASSWORD" \--all-databases \--single-transaction \--routines \--triggers \--events > "$temp_file" 2>> "$LOG_FILE"; then# 压缩备份文件if gzip -c "$temp_file" > "$backup_file"; thenrm -f "$temp_file"local file_size=$(du -h "$backup_file" | cut -f1)log_success "备份完成: $backup_file (大小: $file_size)"elselog_error "压缩备份文件失败"rm -f "$temp_file"exit 1fielselog_error "数据库备份失败"rm -f "$temp_file"exit 1fi
}# 清理旧备份
cleanup_old_backups() {log_info "清理超过${RETENTION_HOURS}小时的旧备份..."local deleted_count=0local backup_files=("$BACKUP_DIR"/backup_*.sql.gz)if [ ${#backup_files[@]} -gt $RETENTION_HOURS ]; then# 按时间排序,删除最旧的for file in $(ls -t "$BACKUP_DIR"/backup_*.sql.gz | tail -n +$(($RETENTION_HOURS + 1))); dorm -f "$file"((deleted_count++))log_info "删除旧备份: $(basename "$file")"donelog_success "已删除 $deleted_count 个旧备份文件"elselog_info "无需清理,当前备份文件数: ${#backup_files[@]}, 保留限制: $RETENTION_HOURS"fi
}# 验证备份文件
verify_backup() {local latest_backup=$(ls -t "$BACKUP_DIR"/backup_*.sql.gz 2>/dev/null | head -1)if [ -n "$latest_backup" ]; thenif gzip -t "$latest_backup" 2>/dev/null; thenlog_success "备份文件验证成功: $(basename "$latest_backup")"return 0elselog_error "备份文件损坏: $(basename "$latest_backup")"return 1fielselog_error "未找到备份文件"return 1fi
}# 发送通知(可选)
send_notification() {local status=$1local message=$2# 这里可以集成邮件、Slack、钉钉等通知# 示例:发送到系统日志logger "MySQL备份: $status - $message"
}# 主备份函数
main_backup() {log_info "========== MySQL备份开始 =========="check_dependenciescreate_backup_dirif perform_backup; thenif verify_backup; thencleanup_old_backupssend_notification "成功" "数据库备份完成"log_success "========== MySQL备份完成 =========="return 0elsesend_notification "失败" "备份文件验证失败"log_error "========== MySQL备份失败 =========="return 1fielsesend_notification "失败" "数据库备份过程失败"log_error "========== MySQL备份失败 =========="return 1fi
}# 设置定时任务
setup_cron() {local cron_job="0 * * * * /bin/bash $PWD/$(basename "$0")"if ! crontab -l | grep -q "$(basename "$0")"; then(crontab -l 2>/dev/null; echo "$cron_job") | crontab -log_success "已设置每小时定时任务"elselog_info "定时任务已存在"fi
}# 显示备份状态
show_status() {echo -e "${BLUE}=== MySQL备份状态 ===${NC}"echo "备份目录: $BACKUP_DIR"echo "日志文件: $LOG_FILE"echo "保留时间: $RETENTION_HOURS 小时"echo ""local backup_count=$(ls "$BACKUP_DIR"/backup_*.sql.gz 2>/dev/null | wc -l)echo "当前备份文件数: $backup_count"if [ $backup_count -gt 0 ]; thenlocal latest_backup=$(ls -t "$BACKUP_DIR"/backup_*.sql.gz | head -1)local backup_size=$(du -h "$latest_backup" | cut -f1)local backup_time=$(stat -c %y "$latest_backup" | cut -d'.' -f1)echo "最新备份: $(basename "$latest_backup")"echo "备份时间: $backup_time"echo "文件大小: $backup_size"fiecho ""echo "定时任务:"crontab -l | grep "$(basename "$0")" || echo "未设置定时任务"
}# 主函数
main() {case "${1:-}" in"setup")setup_cron;;"status")show_status;;"run")main_backup;;"test")# 测试备份log_info "测试备份功能..."main_backup;;*)echo -e "${GREEN}MySQL数据库备份脚本${NC}"echo "用法: $0 [command]"echo ""echo "命令:"echo " run 执行一次备份"echo " setup 设置每小时定时任务"echo " status 显示备份状态"echo " test 测试备份功能"echo ""echo "示例:"echo " $0 run # 执行备份"echo " $0 setup # 设置定时任务"echo " $0 status # 查看状态";;esac# 执行主函数
main "$@"
}
安装和使用说明
- 保存脚本并赋予执行权限
bash
保存脚本
nano mysql_hourly_backup.sh
chmod +x mysql_hourly_backup.sh
创建备份目录
sudo mkdir -p /opt/mysql/backups
sudo chmod 755 /opt/mysql/backups
- 测试备份功能
# 测试备份
./mysql_hourly_backup.sh test# 手动执行一次备份
./mysql_hourly_backup.sh run# 查看备份状态
./mysql_hourly_backup.sh status
- 设置每小时定时任务
# 设置定时任务
./mysql_hourly_backup.sh setup# 验证定时任务
crontab -l# 手动立即执行一次备份
./mysql_hourly_backup.sh run
4. 查看备份文件
bash
# 查看备份文件
ls -la /opt/mysql/backups/# 查看备份日志
tail -f /var/log/mysql_backup.log
- 恢复数据库(如果需要)
# 解压备份文件
gzip -d /opt/mysql/backups/backup_20250921_120000.sql.gz# 恢复数据库
docker exec -i mysql mysql -uroot -proot123 < /opt/mysql/backups/backup_20250921_120000.sql
定时任务说明
脚本会自动设置cron任务,每小时整点执行一次备份:text
0 * * * * /bin/bash /path/to/mysql_hourly_backup.sh run
功能特点
✅ 每小时自动备份
✅ 压缩备份文件节省空间
✅ 自动清理24小时前的旧备份
✅ 备份验证和错误处理
✅ 详细的日志记录
✅ 邮件通知(可扩展)
✅ 易于安装和配置
自定义配置
您可以编辑脚本开头的配置变量:
MYSQL_CONTAINER="mysql" # MySQL容器名
MYSQL_USER="root" # MySQL用户名
MYSQL_PASSWORD="root123" # MySQL密码
BACKUP_DIR="/opt/mysql/backups" # 备份目录
RETENTION_HOURS=24 # 保留小时数