rsync 加 systemd 定时器做增量备份
照片和文档我放在家里的小主机上,再每天同步一份到另一块盘。试过几个备份软件之后,最后还是回到了 rsync 加 systemd 定时器:没有图形界面,但足够简单,出了问题也看得懂。
用硬链接做增量快照
rsync 的 --link-dest 参数很好用:没有变化的文件直接硬链接到上一次的快照,只有改过的文件才真正复制。每个快照目录看起来都是完整的,占的空间却只有增量部分。
#!/usr/bin/env bash
set -euo pipefail
src=/srv/data/
dest=/mnt/backup/snapshots
today=$(date +%F)
rsync -a --delete \
--link-dest="$dest/latest" \
"$src" "$dest/$today"
ln -sfn "$dest/$today" "$dest/latest"
第一次运行时 latest 不存在,rsync 会给个提示然后做完整复制,不影响结果。
清理旧快照
我保留最近 30 天,再早的删掉。因为是硬链接,删掉旧目录不会影响新快照里的文件:
find "$dest" -maxdepth 1 -type d -name '20*' -mtime +30 -exec rm -rf {} +
用 systemd 定时器代替 cron
相比 cron,定时器的好处是:日志直接进 journald;机器关机错过的任务,开机后会补跑(Persistent=true);还能用 systemctl list-timers 看下一次什么时候执行。
# /etc/systemd/system/backup.service
[Unit]
Description=Daily snapshot backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
Nice=10
IOSchedulingClass=idle
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=*-*-* 03:30:00
RandomizedDelaySec=15m
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
记得验证能恢复
没有恢复过的备份不算备份。我每个月随便挑几个文件,从快照里拷出来和原文件比对一下:
cmp /srv/data/photos/2026/0412.jpg /mnt/backup/snapshots/latest/photos/2026/0412.jpg
另外,同一台机器上的两块盘只能防硬盘坏,防不了误删加同步、也防不了整机出事。重要的东西还是要再放一份到别的地方。