能,但需解决权限、路径、时间戳和失败静默问题:用--single-transaction、绝对路径、~/.my.cnf存密、set -e、gzip压缩、find删旧、rsync推送+校验,并定期恢复测试。
用 mysqldump 配合 cron 做定时全库备份
直接结论:能,但必须处理好权限、路径、时间戳和失败静默问题。很多脚本看着能跑,其实某天 mysqldump 报错后没日志、没通知、没清理旧文件,三个月后磁盘爆满才发现备份全是空的。
实操建议:
-
mysqldump必须用--single-transaction(InnoDB)或--lock-all-tables(MyISAM),否则可能备份出不一致数据 - 输出文件名务必带
$(date +\%Y\%m\%d_\%H\%M),别用$(date +%s)——秒级时间戳在 cron 每分钟执行时容易冲突 - 备份命令前加
set -e,确保任意一步失败就终止,避免继续执行压缩或推送逻辑 - 别把密码写在命令行里(
-p123456),会被ps aux看见;改用~/.my.cnf,并设chmod 600 ~/.my.cnf
cron 执行时找不到 mysqldump 或环境变量
现象:手动运行脚本成功,放进 cron 就报 command not found: mysqldump 或连不上数据库——因为 cron 使用最小环境,$PATH 只有 /usr/bin:/bin,且不加载 ~/.bashrc。
实操建议:
- 用
which mysqldump查绝对路径,脚本里写死,比如/usr/bin/mysqldump - 在 crontab 条目开头显式声明环境:
SHELL=/bin/bash、PATH=/usr/local/bin:/usr/bin:/bin - 测试时加日志重定向:
0 2 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1,否则失败无声无息
备份文件堆积导致磁盘占满
自动备份最常被忽略的不是“怎么存”,而是“怎么删”。没人管的 .sql 文件半年就能吃掉上百 GB。
实操建议:
- 备份完立刻用
gzip压缩,mysqldump ... | gzip > backup_$(date...).sql.gz,体积通常压到 1/4~1/3 - 删除 7 天前的文件用
find /backup -name "*.sql.gz" -mtime +7 -delete,别用ls | head -n -7 | xargs rm——文件名含空格就崩 - 加一句
df -h /backup | awk 'NR==2 {print $5}' | sed 's/%//'做使用率检查,超 85% 就echo "ALERT" | mail -s "backup disk full" admin@example.com
跨服务器推送备份或校验完整性
本地备份只是第一步。真正防误操作或硬件损坏,得把 .sql.gz 推到另一台机器,且不能只靠 scp 成功就认为 OK——网络中断可能传了一半。
实操建议:
- 用
rsync --partial --progress --remove-source-files替代scp,支持断点续传,传完自动删源文件 - 推送后立刻在目标机上校验:
gunzip -t backup_20240501.sql.gz(测试能否解压),再head -n 100 backup_20240501.sql | grep "CREATE TABLE"确认开头是有效 SQL - 别用 root 用户推送到远端;建专用账号
backupuser,限制只能rsync到指定目录,禁用交互 shell
备份链路上每个环节都可能静默失效:MySQL 权限变、磁盘只读、NFS 挂载丢失、SSH 密钥过期……最危险的不是不会配,而是配完从不验证恢复流程。至少每季度拿一个备份文件,真还原到测试库跑一遍 SELECT COUNT(*)。

















