Search This Blog

Monday, April 9, 2007

Organize files backup and upload them to ftp server

This script performs a daily files backup. The goal is to get possibility to restore any file within seven days. To economically waste disk space, the full backup is performed only once within a week on Sunday morning. On all other days only differential backup is performed (backup files changes from last FULL backup only). This technique allows to significantly speedup the restore. Scheme is simple, one full backup followed by six differential ones.

The /usr/local/etc/backup.conf file stores directories to include/exclude to/from backup, syntax is simple: the first "+" means to backup, and the "-" means to exclude from the backup.

cat /usr/local/etc/backup.conf
+/etc
+/usr/local/etc
+/usr/local/opt
+/home
-/home/www/logs
+/var/mail
+/var/qmail/control
+/var/qmail/alias
+/var/cron/tabs
-/var/mail/spam

So, here we go:
cat /usr/local/opt/files_backup.sh
#!/bin/sh
to_backup=/usr/local/etc/backup.conf
backupdir=/path/to/store/backups
ftp_to=ftp://host.name.to.put.backups.to/`hostname -s`/files
# Days to make diffs
diff_days=6
# Days to keep backup
restore_days=7

### Do not edit below
umask 037
PATH=/bin:/usr/bin

date=`date "+%Y-%m-%d"`

# Find last full backup in ${diff_days} days if exists
last_full=`find ${backupdir} -name "*-full.tbz2" -type f -mtime -${diff_days} | sort -r | head -1`

# Enumerate directories to include in backup
for dir in `cat ${to_backup}` ; do
case `expr -- "${dir}" : '\(^.\)'` in
+) include="${include} `expr -- "${dir}" : '+\(.*\)'`" ;;
-) exclude="${exclude} --exclude `expr -- "${dir}" : '-\(.*\)'`" ;;
esac
done

if [ ${last_full} ]; then
if [ "`find ${to_backup} -newer ${last_full}`" ]; then
filesuff="full.tbz2"
else
filesuff="diff.tbz2"
newer="-W newer-mtime-than=${last_full}"
fi
else
filesuff="full.tbz2"
fi
filename=${date}-${filesuff}

# Backup files and put to ftp server
tar jPpcf ${backupdir}/${filename} ${newer} ${exclude} ${include} && \
ftp -Vu ${ftp_to}/${filename} ${backupdir}/${filename}

# Find Last Full Backup to Keep ( LFB2K ) in ${restore_days} days
full2keep=`find ${backupdir} -name '*-full.tbz2' -type f -mtime +${restore_days} | sort -r | head -1`

if [ ${full2keep} ]; then

full2keep_name=`expr "//${full2keep}" : '.*/\(.*\)'`

# Delete files older than LFB2K
find ${backupdir} -type f ! -newer ${full2keep} ! -name ${full2keep_name} -name '*.tbz2' -delete

# Delete unnecessary diff files belongs to LFB2K
find ${backupdir} -type f -newerBm ${full2keep} -Btime +${restore_days} -name '*.tbz2' -delete
fi

This script can be downloaded from here.

There were some fixes and modifications.