<root@linux0 ~>$ cat xtra.sh 
#! /bin/bash
#back up module, use crond run the shell accordingly
#all back module
#and increment back up module
#all backup at sunday 
#other weekdays increment back up
#when run choose function from all and increment

BACKUP_NAME=root
BACKUP_PW=******
BACKUP_DIR=/data/backup
MYSQL_CNF=/etc/my.cnf
MYSQL_SOCK=/tmp/mysql.sock
CRYCLE=`date +%d`    #保存日志的名字,一个月的日志都会保存,一个月以后会被复盖;
BACKUP_LOG=/data/backup/$CRYCLE.log
ALL_DAY="星期四"   #每周四做全量备份;

allbackup () {   #全量备份,过程输出到日志,恢复还需要用到日志;
echo "innobackupex --defaults-file=$MYSQL_CNF --user=$BACKUP_NAME --password=$BACKUP_PW -S $MYSQL_SOCK $BACKUP_DIR &> $BACKUP_LOG"
innobackupex --defaults-file=$MYSQL_CNF --user=$BACKUP_NAME --password=$BACKUP_PW -S $MYSQL_SOCK $BACKUP_DIR &> $BACKUP_LOG
}

incrementbackup () {  #基于前一天做增量备份;
checkincrement
echo "incrementbackup"
echo "innobackupex --defaults-file=$MYSQL_CNF --user=$BACKUP_NAME --password=$BACKUP_PW -S $MYSQL_SOCK --incremental $BACKUP_DIR --incremental-basedir=$BACKUP_DIR/$LAST_FILE &> $BACKUP_LOG"
innobackupex --defaults-file=$MYSQL_CNF --user=$BACKUP_NAME --password=$BACKUP_PW -S $MYSQL_SOCK --incremental $BACKUP_DIR --incremental-basedir=$BACKUP_DIR/$LAST_FILE &> $BACKUP_LOG
}

checkincrement () {   #利用日志查出前一天备份生成的文件名,用于增量备份;
LAST_DATE=`date -d "-1day" +%d`
    if [ `cat $BACKUP_DIR/$LAST_DATE.log |grep "completed" |wc -l` -eq 2 ]
      then
        a=`cat $BACKUP_DIR/$LAST_DATE.log |grep "Starting the backup operation" |awk '{print $2}'|awk -F ':' '{print $1}'`
        b=`cat $BACKUP_DIR/$LAST_DATE.log |grep "Starting the backup operation" |awk '{print $2}'|awk -F ':' '{print $2}'`
        c=`cat $BACKUP_DIR/$LAST_DATE.log |grep "Starting the backup operation" |awk '{print $2}'|awk -F ':' '{print $3}'`
        LAST_FILE=`date -d "-1day" +%Y-%m-%d_$a-$b-$c`
      else

        echo "last backup may not be completed! or log file was modified " > $BACKUP_LOG #or email out;  
        exit
    fi
}

backupmain () {
datealign   #时间同步;
alive    #检查服务是否在运行,运行中才能备份;
WEEKDAY=`date +%A`
case $WEEKDAY in
  $ALL_DAY)   #全量备份的日子,一周中的其中一天;
	allbackup
	;;
  *)
	incrementbackup
	;;
esac
}

datealign () {   #用于把时间同步,借用其他脚本;
  ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  
 # yum -y install kde-l10n-Chinese    #机器要运行一次,之后可以注释掉;
  localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8  
  export LC_ALL=zh_CN.UTF-8 
  echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf
}  

alive () {
if [ `ps aux |pgrep mysql|wc -l` -lt 2 ]
  then
    echo "mysql may not running"
    exit
fi
}

backupmain

#crond backup 3am everyday
#crontab -e    #配合使用的计划任务,每天03:01分备份;
#1 3 * * * /bin/bash /root/xtra.sh  

#
#
#
#
# 
#
#
#
#
#
#
<root@linux0 ~>$ cat recover.sh    #恢复脚本;
#! /bin/bash
# 1 double check all the backup file whether is OK.
# 2 choose a checkpoint
# 3 find the day between today and the checkpoint
# 4 

TODAY=`date +%d`     #今天是几号,用于查出应该用哪些备份文件;
WEEKDAY=`date +%A`   #今天是周几;可看跟全量备份之间有哪些备份文件;
BACKUP_DIR=/data/backup
R_FILE=dirname   #保存备份文件的名字;
MYSQL_CNF=/etc/my.cnf
SQL_USER=mysql   #mysql的用户,数据文件的属主;
FIRST="innobackupex --apply-log --redo-only $BACKUP_DIR"   #恢复命令,增量使用;
SECOND="--incremental-dir=$BACKUP_DIR"   #增量使用; 
THIRD="innobackupex --apply-log $BACKUP_DIR"  #最后步骤,必需;
FOUR="innobackupex --copy-back $BACKUP_DIR"   #最后步骤,必需;

findfile () {
case $WEEKDAY in   #如果周五就有两个备份文件可用,周四的全量和周五早些时候的备份;如此类推;
  "星期五")
        f=1
        ;;
  "星期六")
        f=2
        ;;
  "星期日")
        f=3
        ;;
  "星期一")
        f=4
        ;;
  "星期二")
        f=5
        ;;
  "星期三")
        f=6
        ;;
  "星期四")
        f=0
        ;;
esac

>$BACKUP_DIR/$R_FILE #clean the file;   #清空文件里的内容;

for i in `seq 0 $f`      
  do
    L_DATE=`date -d "-"$i"day" +%d`    #日期就是备份日志的名字;
    echo -e "\033[33m checking $BACKUP_DIR/$L_DATE.log \033[0m"
    if cat $BACKUP_DIR/$L_DATE.log | grep "completed OK!" >/dev/null   #获取日志名字,检查备份文件是否有提示完成;
      then
        echo -e "\033[33m OK. information as below: \033[0m"     
        tail -2 $BACKUP_DIR/$L_DATE.log
        dirname    #成功的日志,查出备份时间,生成文件名;
      else
        echo -e "\033[33m log file situation!! \033[0m"
        exit
    fi
  done
echo -e "\033[33m backup checkpoint listing: \033[0m"
cat $BACKUP_DIR/$R_FILE
}

dirname () {   #生成文件名;
a=`cat $BACKUP_DIR/$L_DATE.log |grep "Starting the backup operation" |awk '{print $2}'|awk -F ':' '{print $1}'`
b=`cat $BACKUP_DIR/$L_DATE.log |grep "Starting the backup operation" |awk '{print $2}'|awk -F ':' '{print $2}'`
c=`cat $BACKUP_DIR/$L_DATE.log |grep "Starting the backup operation" |awk '{print $2}'|awk -F ':' '{print $3}'`
d=`date -d "-"$i"day" +%Y-%m-%d_$a-$b-$c`
echo "$d" >> $BACKUP_DIR/$R_FILE
}

choose () {   #选择恢复的节点;
echo -e "\033[33m please see below checkpoint until the last all backup: \033[0m"
cat $BACKUP_DIR/$R_FILE
while :
  do
    read -p "please select the recover checkpoint:" x    
    if echo $x |egrep [0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2}   #文件名格式一定要对;
        then
          echo -e "\033[33m recover checkpoint is $x \033[0m"
          while :
            do
                read -p "please input yes to begin the recover (no to exit):" n
                    case $n in
                           "yes")    #再次确认恢复;
                                sleep 2
                                break
                                ;;
                           "no")
                                exit
                                ;;      
                           *)   
                                continue
                                ;;      
                    esac
            done
          break
        else
          continue
    fi
  done
}

recover () {
#stop the service
#rm the data dir
if [ $(($LINE-$CLINE)) -eq 0 ]    #选择到全量备份点;
  then
    must   #全量恢复;
  else
    	echo -e "\033[33m **1** $FIRST/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/ \033[0m"
        $FIRST/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/   #增量恢复第一步;
    	echo $?
    	sleep 8
        
    	for i in `seq $(($LINE-1)) -1 $(($CLINE+1))`     #只有一个增量文件,不会实施,两个以上实施;
  	  do
    		echo -e "\033[33m **x** $FIRST/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/ $SECOND/`sed -n "$i"p $BACKUP_DIR/$R_FILE`/ \033[0m"
		$FIRST/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/ $SECOND/`sed -n "$i"p $BACKUP_DIR/$R_FILE`/   #增量加到全量文件里;
    		echo $?
    		sleep 8
  	  done

	echo -e "\033[33m **3** $THIRD/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/ $SECOND/`sed -n "$CLINE"p $BACKUP_DIR/$R_FILE`/ \033[0m"
	$THIRD/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/ $SECOND/`sed -n "$CLINE"p $BACKUP_DIR/$R_FILE`/   #增量的第3步,如果只有一个增量文件,直接实施这一步;
	echo $?
	sleep 8
	must    #最后实施最后两步;
fi  
}

must () {   #全量恢复的步骤,增量恢复的最后两步;
echo -e "\033[33m **4** $THIRD/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/ \033[0m"
$THIRD/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/
echo $?
sleep 8

echo -e "\033[33m **5** $FOUR/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/ \033[0m"
$FOUR/`sed -n "$LINE"p $BACKUP_DIR/$R_FILE`/
if [ $? -eq 0 ]
  then
    chown -R $SQL_USER:$SQL_USER /data/mysql
    service mysqld start
  else
    exit
fi
}

backupdata () {   #备份数据;
RECOVER_DIR=/recoverdir_`date +%m%d_%H%M`   #新建目录;
LINE=`wc -l $BACKUP_DIR/$R_FILE|awk '{print $1}'`     #总的可用于恢复的文件数;
CLINE=`cat $BACKUP_DIR/$R_FILE|grep $x -n |awk -F ':' '{print $1}'`   #选择的恢复节点,在文件名文件的排序;

echo -e "\033[33m backupdata \033[0m"
DATADIR=`cat $MYSQL_CNF |grep datadir |awk -F '=' '{print $2}'`   #利用配置文件,找出数据目录;
echo -e "\033[33m rm -rf $DATADIR.bak \033[0m"
rm -rf $DATADIR.bak   #删除之前的保存;
echo -e "\033[33m /usr/bin/cp -r $DATADIR $DATADIR.bak \033[0m"
/usr/bin/cp -r $DATADIR $DATADIR.bak   #备份;
if [ $? -eq 1 ]
  then
    echo "copy mysql datadir error"
    exit
fi
echo -e "\033[33m rm -rf $DATADIR/* \033[0m"
rm -rf $DATADIR/*   #删除数据,不删除恢复错误;

echo -e "\033[33m *back recover_file*:mkdir $BACKUP_DIR$RECOVER_DIR \033[0m"
mkdir $BACKUP_DIR$RECOVER_DIR    #新建备份文件的备份目录;
for i in `seq $LINE -1 $CLINE`    #把会用到的备份文件保存一份;
  do
    echo -e "\033[33m /usr/bin/cp -r $BACKUP_DIR/`sed -n "$i"p $BACKUP_DIR/$R_FILE` $BACKUP_DIR$RECOVER_DIR/ \033[0m"
    /usr/bin/cp -r $BACKUP_DIR/`sed -n "$i"p $BACKUP_DIR/$R_FILE` $BACKUP_DIR$RECOVER_DIR/
    if [ $? -eq 1 ]
      then
        echo "cope xtra backup file error"
        exit
      else
        sleep 2
    fi
  done
echo -e "\033[33m recover_file backup as $BACKUP_DIR$RECOVER_DIR \033[0m"
ls $BACKUP_DIR$RECOVER_DIR
}

findfile
choose
pkill mysql
backupdata
recover

#
#
#
#
#
#
#
#
#
#
#
#
  • 恢复后,如果再上线,就会产生另一条线的数据,按着备份脚本,基于前一天的备份做备份就会出错
  • 应该把原来的备份日志和备份数据转移,备份到另外一个目录去,再修改备份脚本(修改ALL_DAY=“今天是星期几”),继续执行备份脚本,开始一次全量备份;