能跑通的mysql自动备份脚本,核心在于脚本健壮性、环境可靠性与执行可验证性:必须用--single-transaction等参数保障一致性,检查文件非空和压缩包有效性,显式声明path与绝对路径,密码通过600权限的~/.my.cnf管理,并通过日志、状态文件和清理机制确保全程可控。

Shell 脚本负责执行具体备份逻辑,crontab 负责按时间触发——二者配合不是“加个定时器”那么简单,关键在脚本健壮、环境可靠、执行可验。
备份脚本必须自带检查能力
不能只管 dump,要验证结果是否有效:
- 用 mysqldump --single-transaction --routines --events --triggers --default-character-set=utf8mb4 --hex-blob 保证导出一致性与完整性
- 导出后立即检查文件大小:[ -s "$backup_file" ] || { echo "空文件,备份失败"; exit 1; }
- 对压缩包做基础校验:gzip -t "$backup_file.gz" >/dev/null 2>&1 || { echo "压缩包损坏"; exit 1; }
- 可选:抽样检查 SQL 文件头是否含 CREATE DATABASE 或 DUMP TIMESTAMP 字样
脚本运行环境必须显式声明
crontab 默认 PATH 极简,不声明就会找不到 mysqldump 或 gzip:
- 脚本开头固定写:#!/bin/bash + PATH=/usr/local/bin:/usr/bin:/bin
- 密码绝不写进命令行,改用 ~/.my.cnf(权限必须 chmod 600 ~/.my.cnf)
- 所有路径用变量定义,例如 BACKUP_DIR="/data/backup",后续统一引用 "${BACKUP_DIR}/xxx"
- 执行前强制创建目录:mkdir -p "${BACKUP_DIR}",避免因路径不存在静默失败
crontab 配置要带日志和用户上下文
光写 0 2 * * * /path/to/backup.sh 不够,得知道它到底有没有跑、为什么失败:
- 加日志重定向:0 2 * * * /path/to/backup.sh >> /var/log/mysql-backup.log 2>&1
- 若脚本依赖特定用户(如需读 ~/.my.cnf),用系统级 crontab(/etc/crontab)并明确指定用户:0 2 * * * root /path/to/backup.sh
- 避免用 crontab -e 编辑 root 的任务(容易权限错位),优先走 /etc/crontab 或 /etc/cron.d/ 目录下的独立文件
- 测试时先手动执行:sudo -u root /path/to/backup.sh,模拟 cron 实际运行身份
备份后自动清理+状态反馈
检查不止于“有没有文件”,还要确认“该留的留、该删的删、该报的报”:
- 用 find "$BACKUP_DIR" -name "*.sql.gz" -mtime +7 -delete 清理过期备份
- 备份成功后写一行时间戳到状态文件:echo "$(date '+%F %T') OK" >> /var/run/mysql-backup.status
- 失败时发通知(简单可用 mail 命令,或 curl 推送企业微信/钉钉)
- 每天首次运行时,检查上一次备份是否超时(比如距今 >26 小时),异常则告警











