用 rsync 硬链接做增量备份:每天一份全量快照,磁盘只存一份变化
每天全量复制一次数据,磁盘很快就满了;只存增量文件,恢复时又要按顺序拼很多份。用 rsync 的 --link-dest 做硬链接备份,可以兼顾两者:每天看到的都是一份完整目录,但没有变化的文件在磁盘上只存一份。
一、核心原理:硬链接不是复制
硬链接是同一个 inode 的多个名字。用 ls -i 可以看到,未变化的文件在不同日期的快照里 inode 相同:
ls -i /backup/daily/2026-10-27/config.yaml /backup/daily/2026-10-28/config.yaml
改过的文件会生成新的 inode,旧快照里的旧版本不受影响。删除某一天的快照时,只是删掉一个名字,只有当最后一个名字被删掉,数据块才真正释放。所以回滚到某一天,不需要解包、不需要拼增量,直接进那一天的目录看。
注意前提:源目录和备份目录必须在同一个文件系统里,硬链接不能跨文件系统。
二、一次可用的命令
先准备备份目录,再做第一份全量:
mkdir -p /backup/daily
rsync -a --delete /data/ /backup/daily/2026-10-28/
ln -sfn /backup/daily/2026-10-28 /backup/daily/latest
第二天开始,用 --link-dest 指向上一次快照:
rsync -a --delete --link-dest=/backup/daily/latest /data/ /backup/daily/2026-10-29/
ln -sfn /backup/daily/2026-10-29 /backup/daily/latest
关键点说明:
- -a 保留权限、属主、时间戳和符号链接,备份才像原样。
- 源路径 /data/ 末尾的斜杠表示同步目录里的内容,不带斜杠会多套一层目录。
- –delete 会让快照与源保持一致,源里删掉的文件在新快照里也不会出现,但旧快照里还留着。
- –link-dest 必须指向上一份完整的快照,第一次没有快照时不要加这个参数。
- 每次成功后才更新 latest 软链接,失败的那一次不要覆盖它,否则下一次会拿不完整的目录当基准。
三、验证备份是不是真的省空间
做完两天备份后,对比目录大小和实际占用:
du -sh /backup/daily/2026-10-27 /backup/daily/2026-10-28
du -sh /backup/daily
如果第二天只改了少量文件,两个目录分别看都不小,但合计占用只比一份全量多一点,这就是硬链接在起作用。如果合计占用接近两份全量,先检查是不是跨了文件系统,或者 --link-dest 指错了目录。
再做一次恢复演练,不要等到真出事才验证:
mkdir -p /tmp/restore-test
rsync -a /backup/daily/2026-10-28/ /tmp/restore-test/
diff -r /data /tmp/restore-test
四、写成每天自动跑的脚本
把日期、基准、保留天数写进脚本,避免手敲错目录名:
#!/bin/bash
set -e
SRC=/data/
DEST=/backup/daily/$(date +%F)
LATEST=/backup/daily/latest
mkdir -p /backup/daily
if [ -d "$LATEST" ]; then
rsync -a --delete --link-dest="$LATEST" "$SRC" "$DEST/" >> /var/log/backup.log 2>&1
else
rsync -a --delete "$SRC" "$DEST/" >> /var/log/backup.log 2>&1
fi
ln -sfn "$DEST" "$LATEST"
find /backup/daily -maxdepth 1 -type d -mtime +30 ! -name daily -exec rm -rf {} +
用 crontab 每天凌晨跑一次:
0 2 * * * /usr/local/bin/backup.sh
保留策略按数据重要程度定,上面是保留 30 天。删除旧快照前,先确认最新快照能正常列出文件、日志里没有 rsync 报错。
五、容易踩的坑
- 备份盘和源盘不在同一文件系统,硬链接会静默失效,变成实打实的两份复制。
- 源目录为空或挂载失败时,–delete 可能把新快照同步成空目录,重要目录先检查挂载状态再跑备份。
- 数据库、虚拟机镜像这类正在写的大文件,rsync 抓到的可能是中间状态,关键业务先停写或先做应用层快照,再用 rsync 备份快照。
- 只备份到同一台机器不算异地容灾,重要数据还要再同步一份到另一台机器或对象存储。
总结一句话:–link-dest 让每一天都是一份完整快照,磁盘却只为变化的部分买单。先在测试目录跑两天、验证恢复,再放到正式数据上。
- 点赞
- 收藏
- 关注作者
评论(0)