真正可用的mysql自动备份需确保每次真备份、失败有提醒、旧文件不堆积;关键在规避明文密码、缺失--single-transaction、误用find -mtime三坑,并严格配置环境、路径、权限与校验机制。

用 crontab 定时执行 MySQL 自动备份,关键不在“能跑”,而在“每次真备份、失败有提醒、旧文件不堆积”。手动能跑通的脚本,放进 crontab 常常静默失败,多数卡在环境、权限、路径这三关。
备份脚本必须避开的三个坑
明文密码、不加 --single-transaction、用 find -mtime 清理旧文件——这是线上脚本失效最频繁的三处。
- 密码绝不能写在命令行或脚本里,改用 ~/.my.cnf(如 root 运行就放 /root/.my.cnf),内容只保留 [client] 段,权限严格设为 600
- InnoDB 表必须加 --single-transaction,否则高并发下导出数据可能不一致;MyISAM 表才需配合 --lock-all-tables
- 清理旧备份别依赖 -mtime,它看的是文件修改时间。一次失败备份留下空文件,-mtime 会误判为“新文件”而跳过;应按文件名中日期解析后比对,或至少先校验文件非空再清理
crontab 执行前必做的四件事
脚本在终端能运行 ≠ crontab 能运行。cron 启动时环境极简,PATH 通常只有 /usr/bin:/bin,且不读取 .bashrc 或 /etc/profile。
- 所有命令写绝对路径:/usr/bin/mysqldump、/bin/gzip、/usr/bin/find
- 脚本开头显式声明 PATH:export PATH="/usr/bin:/bin:/usr/local/mysql/bin"
- 重定向 stderr 到日志:2>> /var/log/mysql_backup.log,否则错误全丢掉
- 用 sudo crontab -e 编辑 root 任务——普通用户 crontab 无法访问 MySQL 配置、写系统级备份目录
一个真正可用的最小化备份脚本结构
不追求功能堆砌,只保核心动作可验证:
- 用 set -e 让任意命令失败立即退出
- 备份后立刻检查文件大小:if [ ! -s "$BACKUP_FILE" ]; then echo "empty"; exit 1; fi
- 文件名含秒级时间戳:$(date +\%Y\%m\%d_\%H\%M\%S)(% 要转义,否则 shell 解析错)
- 压缩与导出合并成一步:mysqldump ... | gzip > $BACKUP_FILE,避免中间生成大临时文件
- 备份前检查磁盘空间,超 90% 使用率自动跳过并记录告警
定时规则别写错顺序和权限
crontab 时间格式固定为「分 时 日 月 周」,常见错误是把 0 2 * * *(每天 2 点)写成 2 0 * * *(每月 2 日 0 点)。
- 每天凌晨 2 点执行:0 2 * * * /opt/scripts/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1
- 务必确认脚本有执行权限:chmod +x /opt/scripts/mysql_backup.sh
- 首次添加后,可用 sudo systemctl restart crond 确保服务重载新配置
- 执行几分钟后,检查日志和备份目录,确认文件生成且大小合理(几 MB 起步,空文件或几 KB 就是失败)











