生产环境必须解决密码安全、权限缺失、路径错误、crontab执行上下文差异四类问题:禁用明文密码,改用~/.my.cnf或--defaults-extra-file(权限600);cron中需用绝对路径调用mysqldump并指定--default-character-set=utf8mb4;备份后须校验文件大小与SQL头部,定期抽样恢复验证。

mysqldump 是 MySQL 5.7 官方推荐的逻辑备份工具,但直接裸用容易出错。生产环境必须解决密码安全、权限缺失、路径错误、crontab 执行上下文差异这四类问题。
避免在命令行里写密码:改用 ~/.my.cnf 或 --defaults-extra-file
直接在脚本里写 -u root -p123456 会触发警告,且 mysqldump 在 crontab 下可能完全拒绝执行(尤其启用了 secure_file_priv 或 SELinux 的系统)。正确做法是把凭证存到配置文件里:
- 创建
/root/.my.cnf(仅 root 可读):[client] user=backup_user password=your_strong_password host=localhost
- 或更稳妥地用
--defaults-extra-file指定独立配置(避免污染全局):mysqldump --defaults-extra-file=/etc/mysql/backup.cnf mydb > /backup/mydb_$(date +%Y%m%d).sql
- 注意:该文件权限必须是
600,否则mysqldump会忽略它并报错Warning: Skipping the data file
mysqldump 在 crontab 下失败的常见原因
手动运行脚本成功,但 crontab 里失败——这是生产中最常踩的坑。根本原因是 cron 环境变量极简,不加载 ~/.bashrc,导致:
-
mysqldump命令找不到:没加绝对路径。查位置用which mysqldump,脚本里必须写成/usr/bin/mysqldump或/usr/local/mysql/bin/mysqldump - 中文字符乱码或导出为空:没指定
--default-character-set=utf8mb4,尤其当数据库含 emoji 或生僻字时 - 备份中断在锁表阶段:没加
--single-transaction(InnoDB 表适用),导致备份期间业务写入被阻塞 - 备份文件权限异常:cron 默认 umask 是 022,生成的 .sql 文件属主可能是 root,但后续清理脚本若用普通用户执行会失败
按保留策略清理旧备份,别只靠 find -mtime
find /backup -name "*.sql" -mtime +7 -delete 看似简洁,但 -mtime 依赖文件修改时间(mtime),而备份脚本若先生成空文件再写入,或 NFS 挂载点时钟不同步,会导致误删或漏删。
- 更可靠的做法:按文件名中的日期字符串判断,例如
backup_20260625.sql,用date -d "20260625" +%s转为时间戳比对 - 或限制目录内最多 N 个文件:
ls -t /backup/*.sql | tail -n +8 | xargs rm -f
(保留最新 7 个) - 务必在
rm前加echo测试,避免通配符展开错误导致全盘清空
验证备份可用性,不能只看文件生成
生成一个 1KB 的空 .sql 文件不算备份成功。每次备份后至少做两件事:
- 检查文件大小:
[[ $(stat -c "%s" "$file") -gt 1024 ]] || { echo "Backup too small"; exit 1; } - 抽样验证 SQL 头部是否包含
CREATE DATABASE或INSERT INTO,排除权限不足导致的静默失败 - 每周选一个备份文件,用
mysql -e "source /path/to/backup.sql"快速导入测试库(不恢复到生产)
真正难的不是写脚本,而是让备份这件事在无人值守时持续可靠——每一步都要预设它会失败,并留下可追溯的日志和明确的失败信号。


















