基於XtraBackup的備份有效性檢查腳本

    生產環境的MySQL是通過crontab的方式,定時調度熱備腳本備份數據。目前是通過XtraBackup軟件實現熱備。關於熱備腳本方面,請查看我原先的博客《使用shell實現mysql自動全備、增備&日誌備份》:http://linzhijian.blog.51cto.com/1047212/1891745 ,這裏不再展開說明。

    備份存放:通過XtraBackup的流式備份,將備份異地存放到備份服務器上。

    備份策略:週日全備,週一到週六增備。

    目前缺漏:這些備份數據未能實現有效性檢查,無法探知這些備份是否具有可用性,需要通過一定的機制實現有效性檢測。

    目前在備份機的備份文件列表如下:

drwxr-xr-x 18 mysql mysql 4096 Apr   9 03:28 mysql01_20170409_023001_full
drwxr-xr-x 18 mysql mysql 4096 Apr 10 03:25 mysql01_20170410_023001_incr
drwxr-xr-x 18 mysql mysql 4096 Apr 11 03:26 mysql01_20170411_023001_incr
drwxr-xr-x 18 mysql mysql 4096 Apr 12 03:25 mysql01_20170412_023001_incr
drwxr-xr-x 18 mysql mysql 4096 Apr 13 03:26 mysql01_20170413_023001_incr
drwxr-xr-x 18 mysql mysql 4096 Apr 14 03:26 mysql01_20170414_023001_incr
drwxr-xr-x 18 mysql mysql 4096 Apr 15 03:27 mysql01_20170415_023001_incr
drwxr-xr-x 18 mysql mysql 4096 Apr 16 03:29 mysql01_20170416_023001_full
drwxr-xr-x 18 mysql mysql 4096 Apr 17 03:26 mysql01_20170417_023001_incr

    其中full結尾的說明當天是全備的,incr結尾的說明當天是增備的。

    腳本實現邏輯:自動恢復全備數據,並依次恢復其餘的增備數據到全備數據中,最後將恢復完畢的全備數據用mysqld拉起來,檢查MySQL的錯誤日誌是否有異常報錯來判斷恢復是否正常。

    vim dbrecover.sh

#!/bin/sh
if [ $# -ne 1 ]
then
    echo "usage: `basename $0` [mysql01|mysql02]"
    exit 1
fi
hostname=$1
today=`date +%Y%m%d`
sh /home/mysql/shell/mysql_recover.sh $hostname $today

    vim mysql_recover.sh

#!/bin/sh

if [ $# -ne 2 ]
then
    echo "usage: `basename $0` [mysql01|mysql02|mysql03] 20170501 "
    exit 1
fi

hostname=$1
#hostname="mysql02"
#today=`date +%Y%m%d`
today=$2
#week=`date +%w`
week=`date -d $today +%w`
time1=`date +%s`
timestamp=`date +%Y%m%d%H%M%S`
logdir="/home/mysql/log/mysqlrecoverlog/$hostname/$timestamp"
dir="/mysqlbackup/databak/$hostname/"
fullname="$dir/full_backup_file.txt"
incrname="$dir/incr_backup_file.txt"
datadir=`grep datadir /etc/my.cnf|awk -F \= '{print $NF}'`
errlog=`grep log-error /etc/my.cnf|awk -F \= '{print $NF}'`
n1="0" ##周幾做熱備,週一到週六爲1~6,週日爲0。
n2="6" ##周幾最後一次增備,週一到週六爲1~6,週日爲0。

mkdir $logdir ##創建日誌目錄


function getdir()
{
if [ $week -eq "$n1" ]
then
    fulldir=`find /mysqlbackup/databak/${hostname}/ -type d -name "*${today}*full"`
    #/mysqlbackup/databak/mysql01/mysql01_20170430_023001_full
    if [ ! -n "$fulldir" ] 
    then
        echo "the fulldir not exist!!!" >> $logdir/recover_${timestamp}.log
        exit 1
    fi
    num=`find /mysqlbackup/databak/${hostname}/ -type d -name "*${today}*full"|wc -l` 
    #/mysqlbackup/databak/mysql01/mysql01_20170429_023001_incr
    if [ $num -eq "1" ] 
    then
        echo $fulldir > $fullname
    else
        echo "there are not only full dbbackup in $today, please check!!!" >> $logdir/recover_${timestamp}.log
        exit 1
    fi
    
else
    incrdir=`find /mysqlbackup/databak/${hostname}/ -type d -name "*${today}*incr"`
    if [ ! -n "$incrdir" ]
    then
        echo "the incrdir not exist!!!" >> $logdir/recover_${timestamp}.log
    fi
    num=`find /mysqlbackup/databak/${hostname}/ -type d -name "*${today}*incr"|wc -l`
    if [ $num -eq "1" ]
    then
        echo $incrdir > $incrname
    else
        echo "there are not only incr dbbackup in $today, please check!!!" >> $logdir/recover_${timestamp}.log
        exit 1
    fi        
fi
}

function uncompress()
{
    dir=$1
    /usr/bin/innobackupex --decompress --parallel=8 $dir >>$logdir/uncompress_${timestamp}.log 2>&1
    success_flag=`cat $logdir/uncompress_${timestamp}.log|grep "completed OK"`
    if [ -n success_flag ]
    then
        echo "$dir decompress sucessfully!" >> $logdir/recover_${timestamp}.log
    else
        echo "$dir decompress failed " >> $logdir/recover_${timestamp}.log
        exit 1
    fi
}

function full_recover() 
{    
    fullbakdir=$1
    uncompress $fullbakdir
    /usr/bin/innobackupex --use-memory=2G --apply-log --redo-only $fullbakdir >>$logdir/full_recover_${timestamp}.log 2>&1 
    success_flag=`cat $logdir/full_recover_${timestamp}.log|grep "innobackupex: completed OK"`
    if [ -n "$success_flag" ] 
          then
            echo "the full dbbackup $fullbakdir recovery is success!" >> $logdir/recover_${timestamp}.log
          else
            echo "the full dbbackup $fullbakdir recovery is fail!" >> $logdir/recover_${timestamp}.log
            exit 1 
          fi
}

function incr_recover()
{
    incrbakdir=$1
    fullbakdir=$2
    uncompress $incrbakdir
    uncompress $fullbakdir
    if [ $week -ne "$n2" ]
    then
        /usr/bin/innobackupex --use-memory=2G --apply-log --redo-only --incremental-dir=$incrbakdir $fullbakdir >>$logdir/incr_recover_${timestamp}.log 2>&1
    else
        /usr/bin/innobackupex --use-memory=2G --apply-log --incremental-dir=$incrbakdir $fullbakdir >>$logdir/incr_recover_${timestamp}.log 2>&1
    fi
    success_flag=`cat $logdir/incr_recover_${timestamp}.log|grep "innobackupex: completed OK"`
        if [ -n "$success_flag" ] 
        then
                echo "the incr dbbackup $incrbakdir recovery is success!" >> $logdir/recover_${timestamp}.log
        else
                echo "the incr dbbackup $incrbakdir recovery is fail!" >> $logdir/recover_${timestamp}.log
                exit 1 
        fi
}

function mysqlrecover()
{
    fullbakdir=$1    
    #uncompress $fullbakdir
    rm -fr $datadir
    /bin/ln -s $fullbakdir  $datadir
    chown -R mysql:mysql $datadir 
    chown -R mysql:mysql $fullbakdir
    /sbin/service mysqld start
    error_flag=`grep -i error $errlog`
        if [ -z "$error_flag" ]
        then
                echo "the mysqld don't report error, mysql recover is success!" >> $logdir/recover_${timestamp}.log
        else
                echo "the mysqld report error, mysql recover is fail, please check!" >> $logdir/recover_${timestamp}.log
                exit 1
        fi
    /sbin/service mysqld stop
    
}

getdir

if [ $week -eq "$n1" ]
then
    full=`cat $fullname`
    full_recover $full
else
    incr=`cat $incrname`
    full=`cat $fullname`
    incr_recover $incr $full
    if [ $week -eq "$n2" ]
    then
        mysqlrecover $full
    fi
fi

time2=`date +%s`
times=$((${time2}-${time1}))
echo "it takes $times seconds to finish the recover!!!" >> $logdir/recover_${timestamp}.log

    備份機目前採用二進制包安裝MySQL的方式,直接上傳到/usr/local/mysql目錄上,配置好相應的/etc/profile和/etc/my.cnf即可。

cat /etc/my.cnf

[mysqld]
datadir=/mysqlbackup/mysql_test
socket=/mysqlbackup/mysql_test/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
[mysqld_safe]
log-error=/mysqlbackup/mysql_test/mysqld.log
pid-file=/mysqlbackup/mysql_test/mysqld.pid

    生成的日誌文件如下:

-rw-r--r-- 1 root root 613918 May  4 09:34 incr_recover_20170504092501.log
-rw-r--r-- 1 root root   307 May  4 09:34 recover_20170504092501.log
-rw-r--r-- 1 root root 259310 May  4 09:26 uncompress_20170504092501.log

其中:

uncompress_20170504092501.log:解壓備份文件時產生的日誌信息

incr_recover_20170504092501.log:XtraBackup應用備份文件時產生的日誌信息

recover_20170504092501.log:當次恢復備份文件記錄的簡要日誌信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章