Everyone should be backing up their data. This just doesn't go towards sysadmins, but even people at home who never even think of it. Just like everything else in I.T., hard drives were built to fail. If you do not make efficient back ups, you are at your own mercy when your drive will no longer spin up, meaning all that data is now gone.
I try to make as many of my tasks as easy as possible simply by using Bash scripting. Its the most portable language meaning 99.9% of the time, you aren't going to need bash to run the script...and even if so, most of the code I write can work with other shells as well.
I'm going to copy/paste parts of my script, and give details about each block of code. At the end, I'll also provide a link to the full script.
What WIll This (Not) Do?
This script will do the following:
- Back up the specified directories
- Create a directory based on month & date
- Create a separate backup for each given device
- E-mail you the results (this assumes a working SSMTP, which is out of the scope of this particular guide)
Lets Begin
Code:
DAY=`date +%d` MONTH=`date +%m` YEAR=`date +%Y`
Code:
# Backup directory to use (2011/08/31 for 08.31.2011)
BKDIR="/backups/$YEAR/$MONTH/$DAY"
if [ ! -d "$BKDIR" ]; then
mkdir -p $BKDIR
fi
Code:
BKLOG="/backups/$YEAR/$MONTH/$DAY.log"
Code:
ARRPOS=0
Code:
DRIVE=('sda' 'sdb')
Code:
BACKUP=('/' '/pub')
Code:
SDAEX=('/media' '/tmp' '/dev' '/proc' '/sys' '/mnt' '/pub' '/var/cache' '/backups')
Code:
touch $BKLOG
Code:
echo "To: someone@somewhere.com" > $BKLOG echo "From:Backups <backups@secrets>" >> $BKLOG echo -e "Subject: Generated backup report for `hostname` on $YEAR.$MONTH.$DAY\n" >> $BKLOG echo -e ">> Backup for: $YEAR.$MONTH.$DAY started @ `date +%H:%M:%S`\n" >> $BKLOG
Code:
# Checks to see if day = 1, and if so, backs up the last month's backups
if [ "$DAY" == "01" ]; then
M=`echo -n $MONTH | awk '{printf substr($1,2)}'`
let OLD=M-1
echo "- New month detected. Backing up previous month's ($OLD) backups." >> $BKLOG
echo " + Backup file: /backups/$YEAR/$OLD.tar.gz" >> $BKLOG
SD=$( { time tar -cpPzf /backups/$YEAR/$OLD.tar.gz /backups/$YEAR/$OLD/; } 2>&1 )
# Got stats, delete folder
rm -rf /backups/$YEAR/$OLD
SD=`echo -n "$SD" | grep real`
MIN=`echo -n "$SD" | awk '{printf substr($2,0,2)}'`
SEC=`echo -n "$SD" | awk '{printf substr($2,3)}'`
echo -e "- done [ $MIN $SEC ].\n" >> $BKLOG
fi
One thing I want to talk about, since its the meat of the actual back up routine, is this line:
Code:
tar -cpPzf /backups/$YEAR/$OLD.tar.gz /backups/$YEAR/$OLD/
Continuing on...
Code:
# Cycle through each drive and back up each
for d in "${DRIVE[@]}"; do
echo "- Backing up drive $d" >> $BKLOG
# By default, at least don't backup lost+found directories
EX="--exclude=lost+found"
# If we are backing up drive 1 (/dev/sda), there's to exclude
if [ $d == "sda" ]; then
for e in "${SDAEX[@]}"; do
EX="`echo -n $EX` --exclude=$e"
done
fi
# Do the magic work and display some cool info
SD=$( { time tar -cpPzf $BKDIR/$d.tar.gz $EX ${BACKUP[$ARRPOS]}; } 2>&1 )
SD=`echo -n "$SD" | grep real`
MIN=`echo -n "$SD" | awk '{printf substr($2,0,2)}'`
SEC=`echo -n "$SD" | awk '{printf substr($2,3)}'`
SD=$(ls -liha $BKDIR/$d.tar.gz)
SIZE=`echo -n $SD | awk '{printf $6}'`
let ARRPOS++
done
Another block of code I didn't discuss earlier (since its in a couple of spots) is this:
Code:
SD=$( { time tar -cpPzf $BKDIR/$d.tar.gz $EX ${BACKUP[$ARRPOS]}; } 2>&1 )
SD=`echo -n "$SD" | grep real`
MIN=`echo -n "$SD" | awk '{printf substr($2,0,2)}'`
SEC=`echo -n "$SD" | awk '{printf substr($2,3)}'`
Code:
[ehansen@sfu ~]$ time real 0m0.000s user 0m0.000s sys 0m0.000s
Code:
for d in "${DRIVE[@]}"; do
Code:
# By default, at least don't backup lost+found directories
EX="--exclude=lost+found"
# If we are backing up drive 1 (/dev/sda), there's to exclude
if [ $d == "sda" ]; then
for e in "${SDAEX[@]}"; do
EX="`echo -n $EX` --exclude=$e"
done
fi
Code:
# Mail this script out...ssmtp for GMail accounts, otherwise change for appropriate MTA /usr/sbin/ssmtp -t < $BKLOG
There you have it...a (surprisingly) simple back up solution for a server. Is it robust? Not really. A better implementation would be to do incremental daily with a full backup only once a week, and to also consider possible locked database files for example, but that's your homework. I encourage people to not steal other people's code, but to build upon it and also learn from it. What I provide will not be a solution for everyone, maybe anyone, but a lot of the techniques found here can be implemented in other languages even (such as PHP...which I converted this script to for fun).
As promised, here is the script, in full (with some poor comments in the header) that you can wget with: http://eric-hansen.info/old/scripts/script/backup.sh






Categories Widget (Show All)
Popular Tags