btrfs is teh win.  No, seriously.  It’s not the only file system that can do this, but it’s the first one I’ve had installed, and it’s beautiful, man.

I got myself a little 2TB external USB 3.0 hard drive ($99!  Past Sean, be very jealous) and wrote a backup script; my first version had all of this complex Towers of Hanoi rotation scheme, but then I realized I didn’t need any of it if I used btrfs’s snapshots.  Now, my backup script consists mainly of:

sg_start --start /dev/sdh   # Tell the drive to spin up
mount /dev/sdh1 /mnt/backups
btrfsctl -s /mnt/backups/backup-$todays_date \
            /mnt/backups/backup-$yesterdays_date
rsync -va --numeric-ids --delete-before --ignore-errors \
      --partial --inplace $backup_paths \
      /mnt/backups/backup-$todays_date
sync
umount /mnt/backups
sg_start --stop /dev/sdh

It does a little more than that (error checking, logging, etc), but not much more.  After the first backup, the disk usage was 15GB; ten days later, I have ten incremental backups, and it’s still 15GB.

Of course, the problem with this is that snapshots are, essentially, COW hard links; this means that if there’s a corruption on the disk for a file, it’ll affect all child snapshots.  My mitigation is to add another backup disk: they’re only $99 (cripes, I can’t get over that price), and each backup is taking about 8 minutes to run (most of that time is spent in rsync, detecting changes) – I can easily affordable to run two backups a night.  It’s not as safe as a rotation backup, but it’s safe enough.