Skip to content

Instantly share code, notes, and snippets.

@ashrafsharif
Created January 11, 2021 05:17
Show Gist options
  • Save ashrafsharif/9382cb5ed571941765304e89193ac392 to your computer and use it in GitHub Desktop.
Save ashrafsharif/9382cb5ed571941765304e89193ac392 to your computer and use it in GitHub Desktop.
A bash script to create xtrabackup full and incremental backups using cron.
#!/bin/bash
# Create a full or incremental xtrabackup
# In the cron job, set it like below:
## xtrabackup weekly full backup (Saturday, 9 PM UTC == Sunday, 5 AM MYT)
## 0 21 * * 6 /root/backups/scripts/xtrabackup.sh full > /dev/null
## xtrabackup daily incremental backup (Sunday->Friday, 9 PM UTC == Monday->Saturday, 5 AM MYT)
## 0 21 * * 0-5 /root/backups/scripts/xtrabackup.sh incremental > /dev/null
# Note:
## - For every full backup taken, all created incremental backups will be deleted.
## - Incremental backup directory will be created automatically with increment of N+1. E.g, if directory "incremental1" exists,
## it will create "incremental2" instead. If no "incrementals" directory exists, it will start with "incremental1".
start=`date +%s`
[ -z $1 ] && echo 'Please specify either full or incremental' && exit 1
if [ $1 == "full" ]; then
FULL=1
elif [ $1 == "incremental" ]; then
FULL=2
else
echo 'Unknown option. Please specify either full or incremental'
exit 1
fi
BACKUP_USER='backup'
BACKUP_PASS='mys3cr3t'
DBPATH=/media/backup/mysql-backups/xtrabackup
FULLBACKUP=$DBPATH/full
INCBACKUPDIR=$DBPATH/incrementals
TIMESTAMP=$(date +'%Y-%m-%d_%H-%M-%S')
BACKUP_LOG=$DBPATH/innobackupex.log
CHECKPOINT=$DBPATH/base
HOSTNAME=$(hostname)
#TELEGRAM=/usr/bin/telegram
TELEGRAM=/bin/telegram
backup_failed() {
local reason=$1
echo "Backup failed. Reason: $reason"
$TELEGRAM "Backup failed. Reason: $reason"
exit 1
}
if [ $FULL -eq 1 ]; then
$TELEGRAM "Backup xtrabackup (full) started at $(date) on $HOSTNAME.."
# if full backup
BACKUP_LOG=$DBPATH/innobackupex.full.log
rm -Rf $FULLBACKUP
#[ -d $FULLBACKUP ] || mkdir -p $FULLBACKUP
[ $? -eq 0 ] && echo "Backing up /var/lib/mysql.." || backup_failed "can't start backup"
ulimit -n 256000 && /usr/bin/innobackupex --user ${BACKUP_USER} --password ${BACKUP_PASS} --slave-info --socket=/var/lib/mysql/mysql.sock --no-timestamp $FULLBACKUP 2>&1 | tee $BACKUP_LOG
[ $? -eq 0 ] && echo "Checking $BACKUP_LOG" || backup_failed "innobackupex failed. Check $BACKUP_LOG"
tail -1 $BACKUP_LOG | grep -i "completed ok"
[ $? -eq 0 ] && echo "Backup looks ok." || backup_failed "innobackupex failed. $(tail -20 $BACKUP_LOG)"
[ -d $CHECKPOINT ] || mkdir $CHECKPOINT
[ -e $CHECKPOINT/xtrabackup_checkpoints ] && rm -f $CHECKPOINT/xtrabackup_checkpoints
cp -f $FULLBACKUP/xtrabackup_checkpoints $CHECKPOINT/
[ $? -eq 0 ] && echo 'Checkpoint created.' || backup_failed "Creating $CHECKPOINT failed."
# wipe off incrementals so it will start the first incremental based on this full backup
rm -Rf $INCBACKUPDIR/*
BACKUPFILE=$FULLBACKUP
else
# if incrementals
$TELEGRAM "Backup xtrabackup (incremental) started at $(date) on ${HOSTNAME}.."
[ -d $INCBACKUPDIR ] || mkdir -p $INCBACKUPDIR
latest_no=$(ls -1 $INCBACKUPDIR | tail -1 | sed 's/[^0-9]*//g')
if [ -z $latest_no ]; then
CHECKPOINT=$DBPATH/base
incbackup_no=1
else
CHECKPOINT=$INCBACKUPDIR/incremental${latest_no}
incbackup_no=$((latest_no + 1))
fi
INCBACKUPPATH=$INCBACKUPDIR/incremental${incbackup_no}
BACKUP_LOG=$INCBACKUPDIR/innobackup.incr.${incbackup_no}.log
echo "CHECKPOINT PATH: $CHECKPOINT"
echo "BACKUP PATH: $INCBACKUPPATH"
[ -f $CHECKPOINT/xtrabackup_checkpoints ] && echo "Backing up /var/lib/mysql.." || backup_failed "can't start backup. checkpoint missing"
ulimit -n 256000 && /usr/bin/innobackupex --user ${BACKUP_USER} --password ${BACKUP_PASS} --no-timestamp --slave-info --socket=/var/lib/mysql/mysql.sock --incremental $INCBACKUPPATH --incremental-basedir=$CHECKPOINT 2>&1 | tee $BACKUP_LOG
[ $? -eq 0 ] && echo "Checking $BACKUP_LOG" || backup_failed "innobackupex failed. Check $BACKUP_LOG"
tail -1 $BACKUP_LOG | grep -i "completed ok"
[ $? -eq 0 ] && echo "Backup looks ok." || backup_failed "innobackupex failed. $(tail -20 $BACKUP_LOG)"
BACKUPFILE=$INCBACKUPPATH
fi
end=`date +%s`
runtime=$((end-start))
totaltime=$(date -d@${runtime} -u "+%Hh %Mm %Ss")
echo "Backup completed in $totaltime"
$TELEGRAM "Backup completed on $HOSTNAME in ${totaltime}, size $(du -sh ${BACKUPFILE})"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment