Chris G cl@isbd.net wrote:
Well here's my initial attempt at writing the incremental backup using rsync's --link-dest :- ...[weekly rotating backup script]
I got this going on my file server (not a NAS - it's a Debian box) using the following script, which can be executed at any interval that seems appropriate*, and retains a specified quantity of previous backups rather than a time limited number. I find that so little changes between backups that I can keep 100 of them on the same size backup media as the main storage (1TB, ~60% full).
This should work in ash almost as-is, but you may need to use dc for the maths (subtracting 1) instead of shell built-in capability: TGT=`echo $BKP 1 -pq|dc`
Notes: - This keeps the backup device mounted read-only unless a backup is in progress, to avoid 'finger trouble' nuking important stuff. - Uses the noatime option when mounted rw, to improve performance. - Since this is a full file system backup, it excludes rather than includes folders. - It doesn't try to back up if there is <10G of free space on the backup device (empirical determination, typically I see 10-20G of change at worst per backup). - Error messages (and debug) to stderr as this is run by cron so will get emailed to root (me). - Any issues are collected and stored in the backup folder.
Phil. * - currently every 4 hours during the day but not overnight since the machine may be busy using my free overnight bandwidth :) ----8<----
#! /bin/sh # Take a snapshot of the current filesystem (minus snapshot folder and caches)
#DBG=--verbose BACKUP_DEV="UUID=go-look-in-dev-disk-by-uuid-xxxxxxxxxxxx" BACKUP_DIR=/var/backups/snapshot EXCLUDES="/dev /proc /sys /mnt /media /tmp /var/cache /var/lock \ /var/www/.get_iplayer $BACKUP_DIR"
# Time/date records BKSTART=`date`
# Only keep up to 100 snapshots MAX_BACKUP=100 # 10GB in k MIN_SPACE_K=10000000
docmd() { [ -n "$DBG" ] && echo debug: "$*" >&2 $* }
NEED_REMOUNT= remount() { docmd mount -o remount,ro $BACKUP_DEV $BACKUP_DIR }
barf() { echo "$*" >&2 [ -n "$NEED_REMOUNT" ] && remount exit 1 }
# Mount the snapshot folder read-write docmd mount -o remount,rw,noatime $BACKUP_DEV $BACKUP_DIR [ $? -eq 0 ] || barf "unable to remount $BACKUP_DIR rw" NEED_REMOUNT=1
# Space check docmd cd $BACKUP_DIR AVAIL=`df -k . |tail -1 |(read d b u a t; echo $a)` [ $AVAIL -gt $MIN_SPACE_K ] || barf "out of backup device space" [ -n "$DBG" ] && echo "debug: available space: ${AVAIL}k" >&2
# Rotate existing backups [ -d backup.$MAX_BACKUP ] && docmd rm -rf backup.$MAX_BACKUP BKP=$MAX_BACKUP while [ $BKP -gt 0 ] do TGT=$(($BKP-1)) [ -d backup.$TGT ] && docmd mv backup.$TGT backup.$BKP BKP=$TGT done
# rsync changes into fresh backup, hard-linking unchanged files for p in $EXCLUDES do echo $p >>/tmp/backup-excludes.$$ done docmd rsync $DBG -a --link-dest=$BACKUP_DIR/backup.1 --exclude-from=/tmp/backup-excludes.$$ / $BACKUP_DIR/backup.0
/tmp/sync-log.$$ 2>&1
if [ $? -ne 0 ]; then echo "rsync into $BACKUP_DIR had some problems, see log" >&2 docmd mv /tmp/sync-log.$$ $BACKUP_DIR/backup.0/RSYNC.LOG fi docmd rm -f /tmp/backup-excludes.$$ /tmp/sync-log.$$
# Time/date records BKSTOP=`date` docmd echo "Backup started: $BKSTART, completed: $BKSTOP"
$BACKUP_DIR/backup.0/README.DATES
# Remount read-only NEED_REMOUNT= remount [ $? -eq 0 ] || barf "unable to remount $BACKUP_DIR ro"