Created
July 2, 2014 09:00
-
-
Save simonklee/6680edec8c3bcab9343e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# takes a backup of node | |
workdir=null | |
datavol="" | |
pidfile="/tmp/backup-node.pid" | |
declare -A backup_nodes=() | |
# timings | |
t0=`date +%s` | |
t1=`date +%s` | |
function print_help { | |
echo "Backup mysql | |
Usage: | |
./`basename $0` <volume> [options] | |
Options are: | |
-h|--help show this help | |
" | |
} | |
function step { | |
t1=`date +%s` | |
printf "INFO: %-30s ... %3d sec - OK\n" "$@" "$[$t1-$t0]" | |
t0=`date +%s` | |
} | |
function error { | |
echo "ERR: $@" 1>&2 | |
} | |
function exit_program { | |
local exit_code=0 | |
if [ ! -z $1 ]; then | |
exit_code=$1 | |
fi | |
if [ -e ${pidfile} ]; then | |
rm $pidfile | |
fi | |
exit $exit_code | |
} | |
function fail { | |
error "program terminated" | |
exit_program 1 | |
} | |
function trap_sigint { | |
exit_program 0 | |
} | |
function trap_sigterm { | |
exit_program 0 | |
} | |
function trap_exit { | |
echo "TRAP" | |
exit_program 0 | |
} | |
trap 'trap_sigint' SIGINT | |
trap 'trap_sigterm' SIGTERM | |
#trap 'trap_exit' EXIT | |
function read_config { | |
# read config file if it is present | |
[ -r /etc/backup-node/conf ] && . /etc/backup-node/conf || return 1 | |
step "read config" | |
} | |
function check_input { | |
if [ "$1" != "" ] ; then | |
datavol="$1" | |
if [ "${datavol}" = "/" ]; then | |
datavol="" | |
fi | |
fi | |
# set globals | |
workdir="${datavol}/tmp/mysql-backup" | |
archivedir="${datavol}/var/lib/mysql-backup" | |
step "check input" | |
} | |
function create_workenv { | |
# check if workdir exists, del if directory, else fail | |
if [ -e "${workdir}" ] ; then | |
if [ ! -d "${workdir}" ] ; then | |
error "${workdir} exists, but is not a directory" | |
return 1 | |
else | |
rm -rf "${workdir}" | |
fi | |
fi | |
# create workdir and extract build | |
mkdir -p "${workdir}" || return 1 | |
mkdir -p "${archivedir}" || return 1 | |
cd ${workdir} || return 1 | |
step "create workenv" | |
} | |
function create_archive { | |
if [ "$#" -ne 1 ] ; then | |
error "create_archive <host>" | |
return 1 | |
fi | |
cd ${archivedir} || return 1 | |
# 'DAILY' | |
local d_delete_backup_older_than_days=6 | |
# 'WEEKLY' | |
local w_delete_backup_older_than_days=30 | |
# Dates format for naming backups | |
local date_format="%Y-%m-%d" | |
# Backup folders names | |
local daily_folder='daily' | |
local weekly_folder='weekly' | |
local monthly_folder='monthly' | |
local dailydir="${archivedir}/${host}/${daily_folder}" | |
local weeklydir="${archivedir}/${host}/${weekly_folder}" | |
local monthlydir="${archivedir}/${host}/${monthly_folder}" | |
for i in $dailydir $weeklydir $monthlydir; do | |
if [ ! -d $i ]; then | |
mkdir -p $i || return 1 | |
fi | |
done | |
local filename="${workdir}/${host}.tar.gz" | |
local dailyfile="${dailydir}/${host}_`date +"$date_format"`.tar.gz" | |
local weeklyfile="${weeklydir}/${host}_`date +"$date_format"`.tar.gz" | |
local monthlyfile="${monthlydir}/${host}_`date +"$date_format"`.tar.gz" | |
# Daily backup | |
if [ ! -e $dailyfile ]; then | |
cp $filename $dailyfile || return 1 | |
fi | |
# Weekly backup | |
if [ "`date +"%u"`" = "7" ]; then | |
if [ ! -e $weeklyfile ]; then | |
cp $filename $weeklyfile || return 1 | |
fi | |
fi | |
# Monthly backup | |
if [ "`date +"%d"`" = "01" ]; then | |
if [ ! -e $monthlyfile ]; then | |
cp $filename $monthlyfile || return 1 | |
fi | |
fi | |
find ${dailydir} -name "*.tar.gz" -mtime +${d_delete_backup_older_than_days} -type f -print -exec rm -f {} \; || return 1 | |
find ${weeklydir} -name "*.tar.gz" -mtime +${w_delete_backup_older_than_days} -type f -print -exec rm -f {} \; || return 1 | |
step "create archive" | |
} | |
function create_backup { | |
if [ "$#" -ne 1 ] ; then | |
error "create_backup <host>" | |
return 1 | |
fi | |
cd ${workdir} || return 1 | |
local backupcmd="innobackupex --safe-slave-backup --stream=tar ./" | |
local datadir="${host}-datadir" | |
# create backup and stream it to localhost | |
ssh -o UserKnownHostsFile=/dev/null \ | |
-o StrictHostKeyChecking=no \ | |
root@${host} -C "${backupcmd}" > "${host}.tar" || return 1 | |
# extract backup and flush transactions | |
mkdir ${datadir} || return 1 | |
tar xfi "${host}.tar" -C ./${datadir} || return 1 | |
innobackupex --apply-log --use-memory=1G ./${datadir} || return 1 | |
# compress backup and cleanup | |
tar zcfi "${host}.tar.gz" ./${datadir} || return 1 | |
rm -f "./${host}.tar" || return 1 | |
rm -rf "./${datadir}" || return 1 | |
step "create backup" | |
} | |
function create_backups { | |
cd ${workdir} || return 1 | |
for host in "${backup_nodes[@]}"; do | |
create_backup "${host}" || return 1 | |
create_archive "${host}" || return 1 | |
done | |
step "create backups" | |
} | |
function cleanup { | |
rm -rf "${workdir}" || return 1 | |
step "cleanup backups" | |
} | |
if [ -e $pidfile ]; then | |
error "backup-node.sh is already running (pid `cat ${pidfile}`)." | |
error "if it isn't please delete ${pidfile}" | |
exit 1 | |
fi | |
echo $$ > $pidfile | |
# deploy steps | |
step "begin backup `date`" | |
read_config || fail | |
check_input $@ || fail | |
create_workenv || fail | |
create_backups || fail | |
cleanup || fail | |
exit_program |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment