最轻量可控的mysql定时备份方案是mysqldump结合cron,须禁用脚本明文密码(防ps/history泄露),改用权限600的~/.my.cnf存储凭证;备份需加--single-transaction、--routines、--triggers等参数保障一致性与完整性,并用绝对路径调用命令、重定向日志、find轮转7天旧文件。

直接用 mysqldump + cron 是最轻量、可控性最强的方案,适合 95% 的中小规模 MySQL 部署;不建议在脚本里硬编码密码,也不该依赖 GUI 工具(如 Workbench)做生产级定时任务。
为什么不能把密码写在备份脚本里
明文密码会出现在进程列表、shell 历史、日志甚至 ps aux 输出中,任何有权限查进程的用户都能看到。更糟的是,如果脚本被误设为 world-readable,密码就彻底暴露。
- 正确做法是使用
~/.my.cnf存认证信息,权限必须设为600 -
~/.my.cnf内容示例(注意:必须放在运行备份脚本的用户家目录下):
[client] user = backup_user password = your_strong_password host = localhost port = 3306
之后所有 mysqldump 调用都不再需要 -u/-p 参数,自动读取该文件
mysqldump 备份命令的关键参数怎么选
默认导出不带事务一致性保证,高并发写入场景下可能产生不一致备份。必须加以下参数组合:
-
--single-transaction:对 InnoDB 表启用一致性快照(几乎无锁),但对 MyISAM 无效 -
--routines:导出存储过程和函数 -
--triggers:导出触发器 -
--events:如需导出事件调度器定义,必须显式加上 - 全库备份用
--all-databases;单库用db_name;多库用--databases db1 db2
错误示例:mysqldump mydb > backup.sql —— 缺少一致性与元数据,恢复时大概率报错
cron 定时任务常见失效原因
很多脚本手动执行成功,但 cron 下失败,核心原因是环境变量不同(尤其是 PATH 和当前工作目录)。
- cron 默认
PATH=/usr/bin:/bin,而mysqldump可能在/usr/local/bin/,必须写绝对路径(用which mysqldump确认) - 脚本里所有路径(
backup_dir、临时文件、日志)都必须用绝对路径 - 在 crontab 条目末尾加
>> /var/log/mysql-backup.log 2>&1,否则错误无声消失 - 测试时先用
0 * * * * ...(每小时一次),确认稳定后再调成每天
正确 crontab 示例:
0 2 * * * /usr/bin/bash /backup/mysql/backup.sh >> /var/log/mysql-backup.log 2>&1
备份文件管理容易忽略的细节
只管“生成备份”不管“清理旧备份”,半年后磁盘爆满才是真问题。
-
find删除逻辑要区分文件和目录:删旧文件用-name "*.sql.gz" -mtime +7 -delete;删整个旧日期目录得用-type d -mtime +7 -exec rm -rf {} \; - 压缩必须用
gzip或zstd,别用bzip2(太慢)或裸.sql(体积大、易损坏) - 每次备份后加校验:用
gzip -t ${file}.gz检查压缩完整性,失败则发警报(哪怕只是echo "FAIL" | mail -s "Backup broken" admin@x")
真正健壮的备份不是“能跑起来”,而是“坏掉时你能立刻发现并换方案”。校验和日志记录比多存两天备份重要得多。











