新环境首次配置必须先手动验证mysqldump连通性与权限,再封装脚本、最后用crontab调度;跳过手动验证将导致90%失败源于权限、路径或密码问题。

直接上结论:新环境首次配置,必须先手动跑通 mysqldump 命令,再封装脚本,最后用 crontab 调度;跳过手动验证这步,90% 的失败都卡在权限、路径或密码上。
手动执行 mysqldump 命令验证连通性与权限
这是最容易被跳过的一步,但所有后续问题的根源都在这里。
- 先确认
mysqldump可用:which mysqldump或mysqldump --version - 用最小参数试连(不写密码):
mysqldump -u root -p --single-transaction --databases testdb > /tmp/testdb.sql,回车后手动输密码,看是否成功生成文件 - 如果报错
Access denied,说明账号没SELECT或LOCK TABLES权限;报错Can't connect to local MySQL server,检查socket路径或是否指定了错误的-h - 别急着往脚本里塞密码——先确保交互式能通,再考虑自动化
用 ~/.my.cnf 避免密码明文暴露
生产环境禁止在脚本或命令行里写 -p123456 这类明文密码,~/.my.cnf 是唯一安全且被 mysqldump 原生支持的方式。
- 创建文件:
vim ~/.my.cnf,内容严格如下(注意权限):
[client] user = root password = your_real_password host = 127.0.0.1
- 立即执行:
chmod 600 ~/.my.cnf,否则mysqldump会拒绝读取 - 验证是否生效:
mysqldump --single-transaction --databases testdb > /dev/null,不报错即成功 - 如果 MySQL 运行在非默认端口(如 3307),必须加
port = 3307到[client]段,否则连接会超时
备份脚本必须包含日期命名、压缩和过期清理
一个没带时间戳的备份文件等于没备份;不压缩的备份占空间快得超乎想象;不清理旧文件迟早撑爆磁盘。
- 关键变量要显式声明:
DATE=$(date +%Y%m%d_%H%M%S),别用%F(有些老系统不支持) - 导出+压缩一步到位:
mysqldump --single-transaction --routines --triggers --databases mydb | gzip > $BACKUP_DIR/mydb_$DATE.sql.gz - 清理逻辑用
find最可靠:find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete,注意-mtime +7表示“7天前及更早”,不是“超过7天” - 脚本开头加
set -e,任意命令失败立即退出,避免误以为备份成功
crontab 执行失败的三个隐藏原因
crontab -e 写完保存就以为万事大吉?多数故障出在环境差异上。
-
PATH不一致:crontab 默认PATH=/usr/bin:/bin,而mysqldump可能在/usr/local/mysql/bin/,解决方法是在脚本开头加export PATH="/usr/local/mysql/bin:$PATH" - 没加载用户环境:crontab 不读
~/.bashrc,所以~/.my.cnf能用,但其他自定义变量不行;所有路径必须写绝对路径,比如/backup,别用~/backup - 日志重定向被忽略:务必在 crontab 条目末尾加
> /var/log/mysql_backup.log 2>&1,否则失败无声无息 - 测试 crontab 是否真触发:
0 * * * * date >> /tmp/cron_test.log,等一小时看有没有输出
最常被忽略的点:备份脚本里用的 date 命令,在某些最小化安装的 CentOS 或 Alpine 系统中可能不带 %N 或 %s 支持,统一用 %Y%m%d_%H%M%S 最稳妥;另外,find -delete 在部分老版本 busybox 中不可用,得换成 -exec rm {} \;。











