Restore is the only test that counts
Task
Take an incremental backup set, then prove the thing people assume and rarely check: that you can actually restore from it, and that a missing increment breaks the chain. Learn the rsync trailing-slash and --delete traps on a copy you can afford to get wrong.
Steps
- Take a full (level 0) backup that also STARTS the snapshot file:
tar czg snapshot.snar -f full.tar.gz -C source .. List it withtar tzfbefore trusting it -- confirm the paths are what you expect. The-ghere is not optional: a full taken with plaintar czfrecords nothing, so the next-grun finds no snapshot and quietly takes another FULL backup. - Change the source (add b.txt and c.txt, leave a.txt alone) and take an incremental against the same snapshot file:
tar czg snapshot.snar -f inc1.tar.gz -C source .. List it: it must hold b.txt and c.txt and NOT a.txt. If a.txt is in there, step 1 did not seed the snapshot, and everything after this is two fulls pretending to be a chain. - Change again -- edit a.txt and DELETE b.txt -- and take a second incremental the same way.
- Restore into an empty directory: extract the full, then each incremental in order, every one with
-g /dev/null:tar xzg /dev/null -f inc1.tar.gz -C restore. Confirm the result matches the final source state, including that b.txt is gone. Replay with a plaintar xzfinstead and b.txt comes back: without-g, tar extracts files but ignores the record of what was deleted. - Now break the chain: restore the full and the SECOND incremental only, skipping the first, into
restore-broken. c.txt is missing -- it was only ever captured by the increment you skipped, and nothing later recorded it because it never changed again. That is why an incremental chain must be replayed in full. - Repeat the whole exercise with a differential scheme and show that a restore needs only the full plus one differential -- larger backups, simpler restore.
- Learn the rsync traps on the copies: show that
rsync -a source destandrsync -a source/ destproduce different layouts, and thatrsync -a --deleteshould always be dry-run with-nfirst.
Verify
cd ~/lab-backup
tar tzf full.tar.gz >/dev/null && echo "archive is readable"
tar tzf inc1.tar.gz | grep -q 'a.txt' && echo "inc1 is a FULL -- redo step 1" || echo "inc1 is incremental"
# full restore, replayed with -g /dev/null so the deletion is honoured:
diff -r source restore && echo "restore matches source"
# after skipping an increment, the diff must FAIL:
diff -r source restore-broken >/dev/null 2>&1 || echo "broken chain detected"
rsync -an --delete source/ dest/ | head # dry run shows what --delete would remove
The two diffs are the whole point: the complete chain must reproduce the source exactly, and the broken chain must not. A backup you have never restored is a hypothesis, and step 5 is why.
Notes
tar t before you trust an archive, rsync -n before you trust a --delete, and a real restore before you trust a backup. Each is the cheap check that turns an assumption into a fact, and each is the one skipped right up until the day it matters.
This is an independent study companion for CompTIA Linux+ and is not produced by or endorsed by CompTIA.