Rolling snapshots with rsync and hard links
I wanted a dated copy of a directory every night, without every copy costing the full size of the directory. rsync can do this with hard links: files that did not change are not copied again, they are linked to the same data as in the previous snapshot.
The command
today=$(date +%F)
rsync -a --delete \
--link-dest=/backups/latest \
/srv/data/ /backups/$today/
ln -sfn /backups/$today /backups/latest
On the very first run /backups/latest does not exist yet, so rsync prints a warning and makes a full copy. From then on only changed files take up new space.
Things to know
- Each snapshot looks like a complete directory. You can delete any old one without breaking the others, because the data is only freed when the last link to it is gone.
- Hard links only work inside a single filesystem, so keep all snapshots on the same volume.
- A file that changes a little is stored again in full. This is not block-level deduplication.
- Use
du -shon the newest snapshot and on the whole backup directory to see how much space you actually use; plainducounts each hard-linked file once per run.
Cleaning up
A simple retention rule is to delete snapshot directories older than a number of days with find, but never the one that latest points to.