可靠的MySQL备份需封装脚本并正确配置crontab:设置变量、创建目录、mysqldump加--single-transaction、压缩与清理旧文件;注意权限、PATH、密码安全(用~/.my.cnf)、日志记录及非交互环境测试。

用 crontab 定时备份 MySQL 数据库,核心是写好备份脚本 + 正确配置定时任务。关键点在于权限、路径、环境变量和错误处理,很多失败是因为脚本在 cron 环境下执行时找不到命令或连不上数据库。
写一个可靠的 MySQL 备份脚本
不要把 mysqldump 命令直接塞进 crontab 里,先封装成 shell 脚本,方便调试和复用:
- 脚本示例(保存为
/home/user/bin/backup_mysql.sh):
#!/bin/bash # 设置变量(按需修改) DB_USER="root" DB_PASS="your_password" DB_NAME="myapp" BACKUP_DIR="/home/user/backups/mysql" DATE=$(date +%Y%m%d_%H%M%S)创建备份目录(如果不存在)
mkdir -p "$BACKUP_DIR"
执行备份(加 --single-transaction 避免锁表,适合 InnoDB)
mysqldump -u"$DB_USER" -p"$DB_PASS" --single-transaction "$DB_NAME" > "$BACKUP_DIR/${DBNAME}$DATE.sql"
可选:压缩备份文件节省空间
gzip "$BACKUP_DIR/${DBNAME}$DATE.sql"
可选:只保留最近 7 天的备份
find "$BACKUP_DIR" -name "${DBNAME}*.sql.gz" -mtime +7 -delete
- 给脚本添加执行权限:
chmod +x /home/user/bin/backup_mysql.sh - 手动运行一次测试:
/home/user/bin/backup_mysql.sh,确认生成文件且无报错 - 注意:生产环境建议用配置文件存密码(如
~/.my.cnf),避免密码明文出现在脚本或进程列表中
配置 crontab 定时任务
用当前用户(如非 root,推荐用数据库操作用户)编辑定时任务:
- 运行
crontab -e - 添加一行(例如每天凌晨 2:30 执行):
30 2 * * * /home/user/bin/backup_mysql.sh >> /home/user/logs/backup_mysql.log 2>&1
-
>>把标准输出追加到日志;2>&1把错误也一起记录,便于排查 - 确保 cron 能找到
mysqldump:可在脚本开头加上PATH=/usr/local/bin:/usr/bin:/bin,或使用绝对路径(如/usr/bin/mysqldump) - 避免使用 % 符号(cron 中有特殊含义),如需日期格式,用
$(date +\%Y\%m\%d)并转义
验证与排错要点
很多备份“看似运行了”,实则静默失败。重点关注这几项:
- 检查 cron 日志:
sudo tail -f /var/log/syslog | grep CRON(Ubuntu/Debian)或sudo journalctl -u cron -f - 确认脚本中所有命令路径正确(cron 默认 PATH 很窄,
which mysqldump查看实际路径) - 测试脚本是否能在非交互式环境下运行(
env -i /bin/bash --noprofile --norc /home/user/bin/backup_mysql.sh) - 如果用 root 的 crontab 备份其他用户的数据库,注意
~/.my.cnf权限必须是 600,且属主匹配 - 定期抽查备份文件是否可解压、SQL 文件是否以
CREATE TABLE开头,不是空文件或报错内容
进阶建议
提升稳定性和运维效率的小技巧:
- 备份前加锁检测或标记(如 touch backup.lock),防止上一次没跑完就启动新任务
- 备份完成后发邮件或写入监控系统(如用
curl推送状态) - 对多库场景,用
mysql -Nse "SHOW DATABASES"动态获取库名,循环备份 - 考虑用
mydumper替代 mysqldump(支持多线程、更细粒度控制),适合大库










