Yet another incremental rsync backup
After using rdiff-backup for about 6 months as a home files backup, I realized it’s a little bit overkill for me. I knew rsync likely versatile enough for my backups, but all I was familiar were just rsync -avz ...
.
After thorough reading of man rsync
, I end up with the following backup scheme:
- make the very first backup: this is just old
rsync -a ...
- subsequent backups should be incremental; i.e. they should contain only files which differ from their previously backed up versions (or was created/deleted)
- each backup should be in its own directory, which should be browseable w/o any additional tools (remember rdiff-backup’s
--list-at-time
option)
Here’s how it works: recent rsync versions have a smart --link-dest=DIR
option. It works like this (with reference to my case): point it to directory with previous backup, so rsync will look this directory before copying file from backup source – if there’s a file identical to one being copied; if such file is found, no real copying is made, instead file from old backup is hardlinked to new backup directory.
So we end up with two backup dirs with unchanged files stored only once and being hardlinked between this backup directories.
All we have to do now is write some simple wrapper script to rotate
backup directories, taking the most recent one into account while creating new backup.
Here’s my approach (not very smart, but it ‘just works’ for me):
#!/bin/bash
set -eu
RSYNC_OPTS="-a -x -H --delete-during --stats -hh -F --max-size=2G"
MOUNTPOINT=/media/portable
BACKUPDIR=$MOUNTPOINT/backup
TODAY=$(date +%Y-%m-%d)
LOGFILE=/tmp/backup.log
mountpoint -q $MOUNTPOINT || { echo $MOUNTPOINT is not a mountpoint ; exit 1; }
[ -d $BACKUPDIR ] || { echo $BACKUPDIR not found ; exit 1; }
if [ ! -L $BACKUPDIR/latest ]
then
# first backup
echo no previous backup, initial run
rsync $RSYNC_OPTS $HOME/ $BACKUPDIR/backup-$TODAY \
&& ln -s backup-$TODAY $BACKUPDIR/latest
else
# previous backup exists
echo previous backup exists, using it
rsync $RSYNC_OPTS --log-file=$LOGFILE --link-dest=$BACKUPDIR/latest $HOME/ $BACKUPDIR/backup-$TODAY \
&& rm $BACKUPDIR/latest && ln -s backup-$TODAY $BACKUPDIR/latest
echo see logfile: $LOGFILE
fi
echo latest backup now is:
readlink -e $BACKUPDIR/latest
I backup my laptop homedir once a week to an external usb-drive mounted to /media/portable
as you may notice. For now I have directories like these: latest
(this is link to the latest backup), backup-2008-05-25
, backup-2008-05-18
, backup-2008-05-11
…
P.S.: I’ve found a nice program, which uses the same approach as described above: mrb, it is based on GNU make and rsync and can be installed on Ubuntu or Debian with sudo apt-get install mrb
.