rsync + 硬链接做增量快照备份
一直想要那种"每天一个完整目录、但只占增量空间"的备份。rsync 的 --link-dest 刚好能做到:没变化的文件直接硬链接到上一份快照,只有变化的文件才真正复制。
脚本
#!/bin/sh
set -eu
SRC=/home/
DEST=/backup
NOW=$(date +%F_%H%M)
rsync -a --delete --link-dest="$DEST/latest" "$SRC" "$DEST/$NOW"
ln -sfn "$DEST/$NOW" "$DEST/latest"
第一次运行时 latest 还不存在,rsync 会提示 link-dest 目录不存在,然后照常做一次完整复制,可以忽略。
几个注意点
SRC末尾的斜杠不能少,否则会在目标里多套一层home目录。- 硬链接只在同一个文件系统内有效,所有快照必须放在同一个分区。
- 每个快照目录都是完整的,恢复时直接复制对应日期的目录即可,不需要像传统增量备份那样按顺序合并。
清理旧快照
目录名按日期命名,排序就是时间顺序,保留最近 30 份:
cd /backup && ls -1d 20*/ | head -n -30 | xargs -r rm -rf
别用 find -mtime 判断新旧:rsync -a 会把快照目录本身的修改时间设成源目录的时间,结果不可靠。
删除旧快照不会影响新快照,硬链接的文件只要还有一个目录引用,数据就还在。配合 systemd timer 每天跑一次,基本就不用管了。