AlmaLinux 10: hard-link incrementals and pruning old backups
Test scope
Section titled “Test scope”In an AlmaLinux 10.2 container (rsync 3.5.0): three --link-dest backups, inode comparisons, history after deleting a file, and actual du usage. Log: plans/content-expansion/evidence/logs/alma-rsync-incremental.log.
Strategy: one directory per day, keep N days
Section titled “Strategy: one directory per day, keep N days”/backup/data/2026-10-20//backup/data/2026-10-19/ ← --link-dest points at the previous dayRun rsync -a --link-dest=<previous day> source/ target/ once a day and unchanged files share inodes. Restoring means entering the dated directory directly — no replaying a full plus incrementals.
Measured: what three backups cost
Section titled “Measured: what three backups cost”rsync -a /var/tmp/src/ /var/tmp/bak/data/2026-10-20-01/du -sh /var/tmp/bak/data/2026-10-20-01592K /var/tmp/bak/data/2026-10-20-01After a change, a second copy:
rsync -a --link-dest=/var/tmp/bak/data/2026-10-20-01 \ /var/tmp/src/ /var/tmp/bak/data/2026-10-20-02/stat -c '%i %n' /var/tmp/bak/data/2026-10-20-01/file1.bin /var/tmp/bak/data/2026-10-20-02/file1.bindu -sh /var/tmp/bak/data/2026-10-20-02142740409 /var/tmp/bak/data/2026-10-20-01/file1.bin142740409 /var/tmp/bak/data/2026-10-20-02/file1.bin788K /var/tmp/bak/data/2026-10-20-02Identical inodes mean shared data; du on 02 alone reads 788K, while the whole set grows by the delta only (792K total after the third backup).
Point-in-time semantics: old backups do not change
Section titled “Point-in-time semantics: old backups do not change”cat /var/tmp/bak/data/2026-10-20-02/notes.txt # v1 + v2cat /var/tmp/bak/data/2026-10-20-01/notes.txt # v1Changes only affect later backups; the older directory keeps the content of its moment — precisely what makes “restore by date” work.
Pruning: deleting a directory is what frees space
Section titled “Pruning: deleting a directory is what frees space”Delete the oldest directory:
rm -rf /var/tmp/bak/data/2026-10-20-01du -sh /var/tmp/bak/dataHard-linked blocks are released only when the last reference disappears, therefore:
- deleting the oldest day frees only the blocks unique to it;
- deleting a middle day leaves the other days intact through their links;
- to reclaim space fast, prune from oldest to newest, never in the middle.
In the test the third backup still totalled 792K and removing file1.bin did not shrink the earlier copies — history remains.
Restoring: take the dated directory
Section titled “Restoring: take the dated directory”rsync -a /var/tmp/bak/data/2026-10-20-01/ /restore/path/Or a single file: cp /var/tmp/bak/data/2026-10-20-01/notes.txt /restore/. Since each directory is a complete view, restoring does not involve rsync at all.
Common traps
Section titled “Common traps”- Relative
--link-dest: resolved against the destination, linking the wrong place; - Missing trailing slash on the source:
srccopies the directory itself, producingtarget/src/...; - Cross-filesystem backups: hard links silently become full copies and usage explodes;
- Pruning with
find -mtime: confirm you are deleting the oldest directory; deleting a middle one frees nothing immediately.
Practice: three backups, prune the oldest, watch the space
Section titled “Practice: three backups, prune the oldest, watch the space”rm -rf /var/tmp/src /var/tmp/bak; mkdir -p /var/tmp/src /var/tmp/bak/datahead -c 200000 /dev/urandom > /var/tmp/src/a.binrsync -a /var/tmp/src/ /var/tmp/bak/data/01/rsync -a --link-dest=/var/tmp/bak/data/01/ /var/tmp/src/ /var/tmp/bak/data/02/rsync -a --link-dest=/var/tmp/bak/data/02/ /var/tmp/src/ /var/tmp/bak/data/03/du -sh /var/tmp/bak/datastat -c '%i %n' /var/tmp/bak/data/0{1,2,3}/a.binrm -rf /var/tmp/bak/data/01du -sh /var/tmp/bak/dataChecks:
a.binhas the same inode in all three directories- Total
duis roughly one copy of the data - After deleting 01 the total barely changes (02 and 03 still reference the blocks)
- Deleting 02 and 03 is when the space returns
常见问题
Why does deleting one backup directory free so little?
Hard-linked blocks are referenced by several directories and are released only when the last reference goes; deleting the oldest day keeps blocks still shared with newer days.
Can rsync prune old backups itself?
No. Keep N days and delete the oldest directories from a script; prune oldest-first so you never remove a middle day that other days still reference.
Does a hard-link backup protect against ransomware?
Not fully. If the backup directory is writable by the attacker, hard-linked files can be overwritten too; keep backups on separate media or mount them read-only.
Next steps
Section titled “Next steps”- Growing storage: LVM growth
- Scheduled jobs: systemd timers
- Log rotation: logrotate in practice