根本原因是cron环境变量与用户shell隔离,需用绝对路径、显式设置SHELL和PATH、避免~符号,并通过~/.my.cnf安全传密;应防anacron补跑、加时间戳、自动压缩清理、空间预警及恢复验证。
crontab 里执行 mysqldump 报错 command not found 或权限拒绝
根本原因是 cron 环境变量和用户 shell 完全隔离,mysqldump 路径没加载,且默认不读取 ~/.bashrc。别指望它自动识别你终端里能用的命令。
- 用
which mysqldump查出绝对路径(比如/usr/bin/mysqldump),脚本里必须写全路径 - 在 crontab 条目开头显式声明
SHELL=/bin/bash和PATH=/usr/local/bin:/usr/bin:/bin - 避免用
~表示家目录,cron 不展开;改用/home/username/或$HOME(但需确保环境变量已设) - 测试时加日志:在 crontab 行末尾追加
>> /var/log/db-backup.log 2>&1
备份脚本里怎么安全传入 MySQL 密码而不暴露在 ps aux 中
直接写 -p'password' 会出现在进程参数里,任何用户都能看到。这不是小题大做,是生产环境基本红线。
- 用 MySQL 配置文件方式:创建
~/.my.cnf,权限设为600,内容写:[client] host=localhost user=backup_user password=your_real_password
- 脚本中调用时只写
/usr/bin/mysqldump --defaults-file=/home/backup/.my.cnf db_name,不带 -p 参数 - 切勿用环境变量(如
MYSQL_PWD)——它也会被子进程继承并可能泄露 - 如果必须用临时凭证,考虑
mysql_config_editor创建 login path,再用--login-path=backup
每天凌晨 2 点备份,但实际执行时间漂移严重
cron 本身不保证精确到秒,但“漂移严重”通常是因为系统休眠、关机、或 cron 服务未运行导致任务堆积。Linux 默认启用 anacron 后,延迟任务会被补跑,反而造成多份重复备份。
- 确认是否启用了 anacron:检查
/etc/anacrontab或systemctl status anacron - 若不需要补跑,把 crontab 条目改成
0 2 * * * ...并确保服务器 24 小时不关机/不挂起 - 加时间戳校验:脚本开头判断当前小时是否为 2,不是就直接 exit,防 anacron 补跑或手动误触发
- 备份文件名必须含
$(date +\%Y\%m\%d_\%H\%M),别只用%Y%m%d,否则同一天多次执行会覆盖
备份文件越来越大,磁盘撑爆前没预警
没人天天盯着 df -h,等报警时往往已丢失最近几天备份。压缩和清理不能靠人肉。
- 导出后立刻用
gzip压缩:/usr/bin/mysqldump ... | gzip > /backup/db_$(date +\%Y\%m\%d).sql.gz - 保留最近 7 天:加一行
find /backup -name "db_*.sql.gz" -mtime +7 -delete - 备份前检查空间:用
df /backup | awk 'NR==2 {print $5}' | sed 's/%//'判断使用率是否超 90% - 检查失败时发邮件或写入 syslog,别只依赖日志文件——没人看日志,等于没监控
真正麻烦的是跨服务器传输、加密存储、以及恢复验证。这些不在 cron 脚本里做,但得有人定期跑一次 gunzip -t 和 mysql -e "SHOW DATABASES;" 确认备份可读。没人验证的备份,和没备份一样。

















