LinuxXLVIII · Backup Toolsrsync tar
rsync and tar - the classic backup tools
What you'll learn
- Use rsync for incremental backup
- Use tar for full and incremental archives
- Capture ACLs, xattrs, SELinux labels and numeric ownership at backup time
- Restore an incremental chain without resurrecting deleted files
- Choose the right tool for the workload
- Avoid common pitfalls
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09
rsync and tar are the classic backup tools. They are the building blocks of every backup strategy. This lesson covers the right patterns.
rsync for incremental backup
rsync is the standard for incremental file backup:
# Production form - see the flag table below
rsync -aAXH --numeric-ids --sparse /var/data/ /backup/data/
# Remote backup
rsync -aAXH --numeric-ids --sparse /var/data/ backup@backup-host:/backup/data/
# With compression
rsync -aAXHz --numeric-ids --sparse /var/data/ backup@backup-host:/backup/data/
# Mirror: delete from the destination what no longer exists at source
rsync -aAXH --numeric-ids --sparse --delete /var/data/ /backup/data/
# Dry run - always do this first with --delete
rsync -aAXHn --numeric-ids --delete /var/data/ /backup/data/
The -a flag is --archive: -rlptgoD (recursive,
symlinks, perms, times, group, owner, devices). Note what is
not in that expansion: -A, -X, -H, -S and -U are all
excluded. -a is the right base, but on its own it is not a
faithful copy of a production filesystem. These are what -a
leaves behind:
| Flag | Preserves | What breaks without it |
|---|---|---|
-A (--acls) | POSIX ACLs | setfacl grants on shared directories vanish |
-X (--xattrs) | Extended attributes, including SELinux labels and file capabilities | SELinux denies sshd/httpd/postgresql after restore |
-H (--hard-links) | Hard-link structure | Each link becomes a separate full copy; the tree grows and link semantics are lost |
--numeric-ids | Raw UID/GID numbers | Names are re-resolved against the destination’s passwd, so a rebuilt host silently reassigns ownership |
-S (--sparse) | Sparse-file holes | A 2 TB sparse image expands to 2 TB of real blocks |
-U (--atimes, rsync 3.2+) | Access times | Age-based retention and audit tooling that reads atime misreads every restored file as freshly touched |
rsync over SSH
For secure remote backup:
rsync -aAXHz --numeric-ids -e ssh /var/data/ backup@backup-host:/backup/data/
For non-default SSH port:
rsync -aAXHz --numeric-ids -e 'ssh -p 2222' /var/data/ backup@backup-host:/backup/data/
Preserving owner, ACLs and xattrs requires root (or
CAP_CHOWN/CAP_FOWNER) on both ends. A backup run as an
unprivileged user silently downgrades to the flags it is
allowed to apply, which is another way to get a copy that looks
complete and is not.
tar for full and incremental archives
tar is the standard for portable archives:
# Full archive - production form
tar --acls --xattrs --xattrs-include='*' --selinux \
--numeric-owner --sparse \
-czf /backup/data-2026-08-09.tar.gz -C /var/data .
# Extract - repeat the same metadata flags
tar --acls --xattrs --xattrs-include='*' --selinux --numeric-owner \
-xzf /backup/data-2026-08-09.tar.gz -C /restore/
# List
tar -tzf /backup/data-2026-08-09.tar.gz
-C /var/data . archives relative paths. Passing
/var/data/ instead makes tar strip the leading / and warn,
and the archive then carries var/data/... prefixes that you
have to strip again at restore. Anchor with -C instead.
--xattrs needs --xattrs-include='*' to be useful: on its
own, GNU tar restores only the system.* namespace by default,
so user.* attributes and anything an application stored there
are dropped. --selinux is shorthand for the
security.selinux label specifically, and is what keeps a
restored RHEL host from being denied by its own policy.
Incremental archives
# Level 0 (full). The .snar file is the state journal.
tar --acls --xattrs --xattrs-include='*' --numeric-owner \
--listed-incremental=/backup/data.snar \
-czf /backup/data-full.tar.gz -C /var/data .
# Level 1+ . Keep a dated COPY of the .snar for each level:
# lose the .snar and the next 'incremental' silently becomes a full.
cp /backup/data.snar /backup/data-$(date +%F).snar
tar --acls --xattrs --xattrs-include='*' --numeric-owner \
--listed-incremental=/backup/data.snar \
-czf /backup/data-incr-$(date +%F).tar.gz -C /var/data .
Restore is the full, then every incremental in order — and
every extraction needs -g /dev/null:
tar -xzf /backup/data-full.tar.gz -g /dev/null -C /restore
tar -xzf /backup/data-incr-2026-08-09.tar.gz -g /dev/null -C /restore
tar -xzf /backup/data-incr-2026-08-10.tar.gz -g /dev/null -C /restore
Choose the right tool
| Need | Use |
|---|---|
| Incremental file copy, network-efficient | rsync |
| Portable archive, full or incremental | tar |
| Network-efficient with compression | rsync -z |
| Many files, deep directory structure | rsync |
| Single archive, easy to move | tar |
| Streamed over network | tar over ssh |
For most production: rsync for local or remote backup, tar for portability.
Knowledge check
Knowledge check · 5 questions
Q1. What does "rsync -a" do?
Q2. rsync over SSH is secure.
Q3. Which of the following are valid rsync options? Select all that apply.
Q4. Nightly backups have run for a year as "tar -czf ...". You are now rebuilding a RHEL host from one of those archives and extract it with "tar --acls --xattrs --selinux -xzf ...". What do you get?
Q5. You restore a level-0 archive and three incrementals with plain "tar -xzf" each. The application then reprocesses queue items that were deleted weeks ago. What went wrong, and what is the fix?
Passing score: 75%. Answers are checked in this browser.