rsync增量备份依赖目标端保留历史文件属性,若目标被清空、权限重置或时间戳篡改,则默认基于修改时间和大小的快速比对失效,导致全量传输。

rsync 增量备份不是自动发生的,它依赖于你是否保留上一次同步的目标目录结构和元数据 —— 没有“历史快照”,就没有增量可言。
为什么 rsync -a --delete 看起来没增量?
很多人执行 rsync -a --delete /src/ user@host:/dst/ 后发现每次都在传全部文件,其实根本原因在于:rsync 的“增量”判断只发生在本地与目标端的文件属性比对阶段。如果目标端被清空、权限被重置、或时间戳被篡改(比如挂载了 noatime 的文件系统),--update 或默认的 quick-check 就会失效。
- rsync 默认用「修改时间 + 文件大小」做快速比对,不校验内容;加
-c会强制 checksum,但大幅降低速度 -
--delete不影响增量逻辑,但它会删掉目标端多余文件,让结果“看起来更干净”,也更容易掩盖同步失败 - 远程路径末尾带不带
/影响极大:/src/表示同步目录内容,/src表示同步目录本身 —— 错一个斜杠,rsync就可能在目标端多建一层嵌套
远程增量备份必须配 SSH 免密登录
定时任务(如 cron)无法交互输入密码,一旦 rsync 触发 SSH 连接卡在 password prompt,整个备份就静默失败。这不是 rsync 的问题,而是 SSH 层的阻塞。
- 生成密钥用
ssh-keygen -t rsa -b 4096,不要用默认 2048 位(部分新系统已警告弃用) - 公钥必须追加进远程用户的
~/.ssh/authorized_keys,且远程~/.ssh目录权限不能大于700,authorized_keys不能大于600 - 测试连通性别只跑
ssh user@host,要跑完整命令:rsync -n -avz /dev/null user@host:/tmp/(-n表示 dry-run)
真正可靠的增量需要保留历史快照
单纯靠 rsync 两次直连同步,只能做到「当前态一致」,无法回溯昨天/上周的文件状态。要实现带时间维度的增量,必须引入硬链接机制。
- 用
--link-dest=PATH参数指定上一次备份目录,rsync 会为未变化文件创建硬链接而非复制,节省空间且保留时间戳 - 典型结构:
/backup/daily.0(当前)、/backup/daily.1(昨日)、/backup/daily.2(前日)…… 每次先mv daily.0 daily.1,再用--link-dest=/backup/daily.1同步到daily.0 - 注意:硬链接仅在同文件系统内有效;跨设备(如不同磁盘、LVM 逻辑卷)会退化为完整复制
备份脚本里最容易漏掉的三件事
一个看似能跑通的 rsync 脚本,往往在线上出问题时才发现缺关键防护。
- 没加
-e 'ssh -o StrictHostKeyChecking=no':首次连接远程主机时,SSH 会卡在 yes/no 提示 —— cron 里完全不可见 - 没检查退出码:
rsync失败时返回非 0 值,但脚本若没写if [ $? -ne 0 ]; then exit 1; fi,就会假装成功 - 没加超时控制:网络抖动可能导致 rsync 卡死,建议加
-e 'ssh -o ConnectTimeout=10 -o ServerAliveInterval=30'
硬链接式增量备份看着简单,但一旦源目录有大量小文件、目标存储是 NFS 或 CIFS,--link-dest 就可能 silently 失效 —— 这时候得看 rsync 输出里的 hard-link 字样是否真出现,而不是只信日志里 “sent XXX bytes”。











