最轻量可控的定时上传方案是crontab调rclone;需绝对路径、flock加锁、错开时间、带UTC时间戳文件名、明确目标路径、上传后校验+告警、日志落盘+rotate、调优transfers/checkers参数。
crontab + rclone 实现定时上传备份文件
直接用 crontab 调 rclone 是最轻量、最可控的方案。别碰那些封装过头的“一键备份工具”,出问题连日志都找不到源头。
常见错误是把备份和上传塞进同一个脚本里,结果某次数据库导出慢了 2 秒,crontab 下一轮又触发,两个进程抢同一个 backup.sql 文件,上传的其实是空文件。
- 先确保
rclone已配置好远程(比如gdrive:或cos://my-bucket),运行rclone ls gdrive:backups能列出内容才算通过 -
crontab中不要用~表示家目录,写绝对路径,比如/home/user/scripts/backup-to-cloud.sh - 给上传任务加锁:在脚本开头用
flock -n /tmp/backup-upload.lock -c "rclone copy ...",避免并发冲突 - 时间建议错开备份任务 5 分钟以上,比如备份在
02 2 * * *(凌晨 2:02),上传设为07 2 * * *(2:07)
备份文件名必须带时间戳且不可覆盖
不带时间戳的 backup.sql 是自毁式设计。哪怕只差 1 秒,两次备份也该是两个独立文件,否则某次上传失败,你就永远丢了那一份。
容易踩的坑是用 date +%Y%m%d —— 精度太低,同一天多次执行会覆盖;或者用 $(date +%s) 但没考虑时区,在服务器上跑出来是 UTC 时间,排查时对不上本地记录。
- 推荐格式:
backup_$(date -u +%Y%m%d_%H%M%S).sql(强制 UTC,避免服务器时区干扰) - 上传命令里明确指定目标路径:
rclone copy /path/to/backup_20240520_020715.sql gdrive:backups/,别用--include模糊匹配 - 上传完成后加校验:
rclone size gdrive:backups/backup_$(date -u +%Y%m%d_%H%M%S).sql输出非零才认为成功
上传失败必须触发告警,不能静默丢弃
默认情况下 rclone 出错只打日志,crontab 的邮件通知又常被当成垃圾邮件过滤。等你发现备份断了两周,云盘里最后的文件还是上个月的。
真实运维中,90% 的“自动化”失效,是因为没人看日志、也没人收告警。
- 在上传命令后接
|| curl -X POST https://your-webhook/backup-fail?host=$(hostname),用企业微信或 Slack webhook 推送 - 别依赖
set -e:某些rclone错误(如网络超时)退出码是 0,得靠rclone ls或rclone md5sum二次确认文件是否真传上去了 - 日志必须落盘:
rclone copy ... >> /var/log/backup-upload.log 2>&1,并用logrotate切割,不然半年后日志文件几十 MB
注意 rclone 的 --transfers 和 --checkers 参数对成功率的影响
默认值(--transfers 4、--checkers 8)在小文件多、网络抖动的场景下极易失败,尤其是国内到境外对象存储(如 Google Drive)。
不是调得越高越好。值太大反而触发云厂商限流,返回 429 Too Many Requests,而 rclone 默认重试策略又不够激进。
- 国内环境建议压低:用
--transfers 2 --checkers 4 --retries 5 --low-level-retries 5 - 大文件(>100MB)可单独处理:加
--s3-upload-concurrency 1防止 COS/S3 分片上传中断 - 务必加
--stats 10s,上传卡住时能从日志看到实时进度,而不是干等 30 分钟再报 timeout
真正麻烦的从来不是“怎么配通”,而是某天凌晨三点,rclone 因为一个临时 DNS 解析失败跳过了整个目录,而你的监控只盯着“进程是否存在”。

















