A linux incremental backup system using DAR
This is a pair of scripts i designed in order to create and restore easily incremental backups of a game server, they allow you to backup automatically a specific folder every 30 minutes every backup is labeled with date hour/minutes/seconds and the script flush every backups that are older than seven days (you can change that obviously)
The system uses incremental updates through the “dar” program, it creates a master backup file every mornings at 0:00 and creates incremental backups every 30 minutes. This means only what changed through the day is saved instead of having one full backup 48 times a day.
this script you should execute through a cron job:
#/bin/sh
#script: backup_incremental.sh
#the folder we want to backup is /home/username/folder_to_backup
WORKING_DIR=/home/username
FOLDER=folder_to_backup
BACKUP_FOLDER=/my/BACKUP
DAY=`date -I`
HOUR=`date +%H%M%S`
#this define the day date of the backups we want to delete
OLD=`date -I -d "-1weeks"`
cd $WORKING_DIR
if [ -f ${BACKUP_FOLDER}/${DAY}.1.dar ]
then
echo "master backup exist, making incremental update."
LASTSLICE=`ls -1cr ${BACKUP_FOLDER}/${DAY}*.dar |tail -1`
echo "last slice is: ${LASTSLICE}"
dar -c ${BACKUP_FOLDER}/${DAY}-${HOUR} -R ${WORKING_DIR}/${FOLDER} -P . -A ${LASTSLICE%%.*}
else
echo "creating daily master backup"
dar -c ${BACKUP_FOLDER}/${DAY} -R ${WORKING_DIR}/${FOLDER} -P .
echo "deleting 7 days old backup (${OLD})"
#we remove the older backups, if we can
rm ${BACKUP_FOLDER}/${OLD}*
fi
Example cron job to execute this script (dev/null is required because dar tend to be quite chatty):
*/30 * * * * /home/user/scripts/backup_incremental.sh >> /dev/null 2>&1
Restoring backups with dar is a little tedious because you have to restore every incremental backups one by one. This script will restore the master backup and every incremental backups up to the one you defined in the folder of your choice.
#/bin/sh
#script: restore_incremental.sh
if [ -n "$3" ]; then
if [ -f "$1" ]; then
if [ -f "$2" ]; then
FS_ROOT="$3"
MASTER_DAR="${1%%.*}"
LAST_BACKUP="${2%%.*}"
FILES=`ls -m1cr ${MASTER_DAR}*.dar`
echo "MASTER DAR FILE is: ${MASTER_DAR}"
echo "LAST BACKUP is: ${LAST_BACKUP}"
echo "File list: ${FILES}"
for file in ${FILES}; do
echo "Processing... ${file}"
dar -Ox ${file%%.*} -w -R "$FS_ROOT"
if [ "${file%%.*}" == "${LAST_BACKUP}" ]; then
echo "This was our last file."
break
fi
done
echo "All done."
else
echo "ERROR: this increment doesn't exist."
fi
else
echo "ERROR: this base dar doesn't exist."
fi
else
echo "Not enough parameters.
Usage:
restore_incremental.sh master_backup.1.dar last_incremental_backup.1.dar /my/destination/folder/"
fi
Great! Certainly helped me get through the DAR man-page more quickly. So now I can say good-bye to tar… 😉