备份脚本中禁止明文写密码,应使用权限为600的~/.my.cnf配置文件存储凭证;crontab时间格式须遵循“分 时 日 月 周”顺序,避免误配导致高频执行;备份需压缩、轮转并验证完整性。

备份脚本里别直接写密码,mysqldump 会暴露在进程列表里
你执行 mysqldump -u root -p123456 db_name,别人用 ps aux | grep mysqldump 就能看见密码。这不是理论风险,是真实发生过的线上事故。
正确做法是用配置文件隔离凭证:
- 新建
~/.my.cnf,权限设为600(chmod 600 ~/.my.cnf) - 内容只写:
[client] user = backup_user password = your_secure_password
- 调用时省略用户和密码:
mysqldump --defaults-extra-file=~/.my.cnf db_name - 确保该文件不属于 root 或其他共享账户,且不在版本控制中
crontab 时间表达式写错,备份就永远不跑
常见错误是把「每小时 15 分执行」写成 15 * * * *(实际是每小时第 15 分钟),但误写成 * 15 * * * 就变成每月 15 号每天每分钟跑一次——磁盘瞬间告急。
实操建议:
- 用
crontab -e编辑,别手写到系统级/etc/crontab,容易权限混乱 - 时间字段顺序固定:分 时 日 月 周,记不住就贴张便签在显示器边
- 加日志重定向,比如:
0 2 * * * /backup/db_backup.sh >> /var/log/db_backup.log 2>&1 - 测试时先用
*/5 * * * *(每 5 分钟)验证脚本逻辑,确认无误再切正式周期
备份文件不压缩、不轮转,三个月后 /backup 目录占满磁盘
裸 SQL 文件体积通常是数据库实际大小的 1.2–1.8 倍;不处理的话,一周就能积攒几十 GB。
必须做的三件事:
- 用
gzip压缩:mysqldump ... | gzip > /backup/db_$(date +\%Y\%m\%d_\%H\%M).sql.gz - 保留最近 7 天:用
find /backup -name "db_*.sql.gz" -mtime +7 -delete - 检查压缩后文件是否有效:
gzip -t /backup/latest.sql.gz,失败就发邮件告警(可用mail -s "Backup broken" admin@example.com)
跨服务器备份时,ssh 密钥没配好,rsync 就卡住不动
脚本里写 rsync -avz /backup/ user@backup-server:/data/,结果 crontab 下完全没反应——因为 cron 环境不加载 ~/.bashrc,导致 ssh agent 不可用,密钥路径或 SSH_AUTH_SOCK 找不到。
解决路径很窄,只有两条靠谱的:
- 用
-i显式指定私钥:rsync -avz -e "ssh -i /home/backup/.ssh/id_rsa" /backup/ user@backup-server:/data/ - 或者改用免交互的
sshpass(仅限内网可信环境):sshpass -f /home/backup/.ssh/passfile rsync -avz ...,但要确保.ssh/passfile权限为600 - 绝对不要在命令行里写明文密码,
rsync的--password-file对 SSH 无效,那是给 rsync daemon 用的
备份最麻烦的从来不是写脚本,而是某天凌晨三点发现上个月的归档根本解不开——gzip -t 那一行,很多人删掉图省事,结果真出问题时连后悔都来不及。










