zoukankan      html  css  js  c++  java
  • MySQL的恢复脚本

    原文转自:

    http://blog.csdn.net/dbanote/article/details/13295727

    应用场景:
    ************************************************************************************************
    
    
    1.备份目录为/backup/full和/backup/incre的架构,前者保存全备,后者保存增量备份
    
    
    2.如全备为/backup/full/2015-04-08_15-14-33则将全备的目录名2015-04-08_15-14-33
    作为/backup/incre/下增量备份的目录名。这样设计的初衷在于只要全备不过期,那么
    这个全备文件之后的增量备份也不过期.
    
    
    3.还原时,脚本会自动找到最新的全备和最新全备命名的增量备份目录,并将增量备份
    按照先后顺序应用日志到全备中,最后完成还原.
    
    
    4.该版本增加了是否恢复所有增量备份,默认是全部增量备份.
    
    
    ************************************************************************************************
    脚本
    ************************************************************************************************
    
    
    #!/bin/sh
    #ocpyang@126.com
    #xtrabackup 2.3.3
    # 使用方法:
    # ./restore.sh /增量备份父目录或全备的父目录名
    #eg1:./restore.sh /data/backup/full/
    #eg2:./restore.sh /data/backup/incre/
    #NOTICE:增量备份还原如果指定文件,则还原到指定文件名的上一个文件末截止.
    #即输入的增量文件名应为需要截止的增量文件名的下一个文件
    
    
    #NOTE:恢复开始前请确保mysql服务停止以及数据和日志目录清空,如
    # rm -rf /data/mysql/innodb_data/*
    # rm -rf /data/mysql/data/*
    # rm -rf /data/mysql/mysql_logs/innodb_log/*
    
    
    echo "*************************************************************************"
    echo -e 'e[32m 提示:mysql端口根据实际环境修改. e[m' #红色
    echo "*************************************************************************"
    
    
    
    
    INNOBACKUPEX=innobackupex
    INNOBACKUPEX_PATH=/usr/local/xtrabackup/bin/$INNOBACKUPEX
    TMP_LOG="/var/log/restore.$$.log"
    MY_CNF=/etc/my.cnf
    BACKUP_DIR=/data/backup # 你的备份主目录
    FULLBACKUP_DIR=$BACKUP_DIR/full # 全库备份的目录
    INCRBACKUP_DIR=$BACKUP_DIR/incre # 增量备份的目录
    MEMORY=2048M # 还原的时候使用的内存限制数
    ERRORLOG=`grep -i "^log-error" $MY_CNF |cut -d = -f 2`
    MYSQLD_SAFE=/data/mysql/bin/mysqld_safe
    MYSQL_PORT=33107
    
    
    
    
    #############################################################################
    
    
    #显示错误
    
    
    #############################################################################
    
    
    error()
    {
        echo "$1" 1>&2
        exit 1
    }
    
    
      
    
    
    #############################################################################
    
    
    # 检查innobackupex错误输出
    
    
    #############################################################################
    
    
    check_innobackupex_fail()
    {
        if [ -z "`tail -2 $TMP_LOG | grep 'completed OK!'`" ] ; then
        echo "$INNOBACKUPEX命令执行失败:"; echo
        echo "---------- $INNOBACKUPEX的错误输出 ----------"
        cat $TMP_LOG
        #保留一份备份的详细日志
        logfiledate=restore.`date +%Y%m%d%H%M`.txt
        cat $TMP_LOG>/backup/$logfiledate  
        rm -f $TMP_LOG
        exit 1
      fi
    }
    
    
     
    
    
    
    
    
    
    # 选项检测
    if [ ! -x $INNOBACKUPEX_PATH ]; then
      error "$INNOBACKUPEX_PATH在指定路径不存在,请确认是否安装或核实链接是否正确."
    fi
    
    
      
    
    
    if [ ! -d $BACKUP_DIR ]; then
      error "备份目录$BACKUP_DIR不存在.请新建备份主目录$BACKUP_DIR"
    fi
    
    
      
    
    
    if [ $# != 1 ] ; then
      error "使用方法: $0 使用还原目录的绝对路径"
    fi
    
    
      
    
    
    if [ ! -d $1 ]; then
      error "指定的备份目录:$1不存在."
    fi
    
    
    
    
    
    
    PORTNUM00=`netstat -lnt|grep ${MYSQL_PORT}|wc -l`
    if [ $PORTNUM00 = 1  ];
    then
    echo -e "e[31m NOTE:------------------------------------------.e[m" #红色
    echo -e "e[31m mysql处于运行状态,请关闭mysql. e[m" #红色
    echo -e "e[31m NOTE:------------------------------------------.e[m" #红色
    exit 0
    fi 
    
    
    ################判断还原增量备份部分还是所有################
    echo "*************************************************************************"
    echo -e "e[31m 输入的增量文件名应为截止的增量文件名的下一个文件.e[m" #红色
    echo "*************************************************************************"
    ipname=''
    read -p "输入截止增量备份名[默认所有]:" ipname
    echo
    
    
    echo "输入截止增量备份名为:$ipname"
    
    
    
    
    input_value=$1
    intpu_res=`echo ${input_value%/*}` 
    
    
    
    
    
    
    # Some info output
    echo "----------------------------"
    echo
    echo "$0: MySQL还原脚本"
    START_RESTORE_TIME=`date +%F' '%T' '%w`
    echo "数据库还原开始于: $START_RESTORE_TIME"
    echo
    
    
    
    
    
    
    
    
    
    
    #PARENT_DIR=`dirname ${intpu_res}`
    PARENT_DIR=${intpu_res}
    
    
    if [ $PARENT_DIR = $FULLBACKUP_DIR ]; then
    FULL=`ls -t $FULLBACKUP_DIR |head -1`
    FULLBACKUP=${intpu_res}/$FULL
    echo "还原完全备份:`basename $FULLBACKUP`"
    echo
    
    
    else
    
    ################判断还原部分增量备份还是所有增量备份################
    if [ "$ipname" = '' ];then
     if [ $PARENT_DIR = $INCRBACKUP_DIR ]; then
    FULL=`ls -t $FULLBACKUP_DIR |head -1`
    FULLBACKUP=$FULLBACKUP_DIR/$FULL
    if [ ! -d $FULLBACKUP ]; then
    error "全备:$FULLBACKUP不存在."
    fi
    INCR=`ls -t $INCRBACKUP_DIR/$FULL/ |sort -nr | head -1 ` #查找最后一个增量备份文件
    echo "还原将从全备全备$FULL开始,到增量$INCR结束."
    echo
    echo "Prepare:完整备份..........."
    echo "*****************************"
    $INNOBACKUPEX_PATH --defaults-file=$MY_CNF --apply-log --redo-only --use-memory=$MEMORY $FULLBACKUP > $TMP_LOG 2>&1
    check_innobackupex_fail
       
    
    
    # Prepare增量备份集,即将增量备份应用到全备目录中,按照增量备份顺序即按照时间从旧到最新
    for i in `find $PARENT_DIR/$FULL -mindepth 1 -maxdepth 1 -type d -printf "%P
    " | sort -n `;
    do
    
    
    #判断最新全备的lsn
    #check_full_file=`find $FULLBACKUP/ -mindepth 1 -maxdepth 1 -type d -printf "%P
    " | sort -nr | head  -1`
       
    check_full_lastlsn=$FULLBACKUP/xtrabackup_checkpoints
       
    fetch_full_lastlsn=`grep -i "^last_lsn" ${check_full_lastlsn} |cut -d = -f 2`
    
    
    ######判断增量备份中第一个增量备份的LSN
    #check_incre_file=`find $PARENT_DIR/$FULL -mindepth 1 -maxdepth 1 -type d -printf "%P
    " | sort -n |  head -1`
         
    check_incre_lastlsn=$PARENT_DIR/$FULL/$i/xtrabackup_checkpoints
         
    fetch_incre_lastlsn=`grep -i "^last_lsn" ${check_incre_lastlsn} |cut -d = -f 2`
    echo "完全备份$FULLBACKUP的LSN值:${fetch_full_lastlsn} "
    echo "增量备份$i的LSN值:${fetch_incre_lastlsn} "
    
    if [ "${fetch_incre_lastlsn}" -eq "${fetch_full_lastlsn}" ];then
    echo "*****************************************"
    echo "LSN相等,不需要prepare!"
    echo "*****************************************"
    echo
    break
    
    
    
    else
    echo "Prepare:增量备份集$i........"
    echo "*****************************"
    $INNOBACKUPEX_PATH --defaults-file=$MY_CNF --apply-log --redo-only --use-memory=$MEMORY $FULLBACKUP --incremental-dir=$PARENT_DIR/$FULL/$i > $TMP_LOG 2>&1
    check_innobackupex_fail
     
    if [ $INCR = $i ]; then
    break
    fi
        
    fi 
    ######判断LSN
    done
    
    else
    error "未知的备份类型"
      fi
    
    
    else
    FULL=`ls -t $FULLBACKUP_DIR |head -1`
    FULLBACKUP=$FULLBACKUP_DIR/$FULL
    echo "Prepare:完整备份..........."
    echo "*****************************"
    $INNOBACKUPEX_PATH --defaults-file=$MY_CNF --apply-log --redo-only --use-memory=$MEMORY $FULLBACKUP > $TMP_LOG 2>&1
    check_innobackupex_fail
    
    
    
    
    
    ipt=`stat -c=%Z  $PARENT_DIR/$FULL/$ipname |cut -d = -f 2`
    echo "还原的指定增量目录文件$ipname的纪元时间为:$ipt"
    for i in `find $PARENT_DIR/$FULL -mindepth 1 -maxdepth 1 -type d -printf "%P
    " | sort -n `;
    do
    #判断for循环取到的文件名是否为输入的文件名,如果是则停止循环
    if [ "$i" =  "$ipname" ]; then
    break;
    else
    f01=`stat -c=%Z  $PARENT_DIR/$FULL/$i |cut -d = -f 2`
    if [ "$f01" -le "$ipt" ]; then
    
    
    if [ $PARENT_DIR = $INCRBACKUP_DIR ]; then
    if [ ! -d $FULLBACKUP ]; then
    error "全备:$FULLBACKUP不存在."
    fi
    #INCR=`ls -t $INCRBACKUP_DIR/$FULL/ |sort -nr | head -1`
    echo "还原将从全备$FULL开始,到增量$ipname结束."
    echo
    
    
    #判断最新全备的lsn
    #check_full_file=`find $FULLBACKUP/ -mindepth 1 -maxdepth 1 -type d -printf "%P
    " | sort -nr | head  -1`
       
    check_full_lastlsn=$FULLBACKUP/xtrabackup_checkpoints
       
    fetch_full_lastlsn=`grep -i "^last_lsn" ${check_full_lastlsn} |cut -d = -f 2`
    
    
    ######判断增量备份中第一个增量备份的LSN
    check_incre_file=`find $PARENT_DIR/$FULL -mindepth 1 -maxdepth 1 -type d -printf "%P
    " | sort -n |  head -1`
         
    check_incre_lastlsn=$PARENT_DIR/$FULL/$i/xtrabackup_checkpoints
         
    fetch_incre_lastlsn=`grep -i "^last_lsn" ${check_incre_lastlsn} |cut -d = -f 2`
    echo "完全备份的LSN:${fetch_full_lastlsn} "
    echo "增量备份的LSN:${fetch_incre_lastlsn} "
    if [ "${fetch_incre_lastlsn}" -eq "${fetch_full_lastlsn}" ];then
    echo "*****************************************"
    echo -e "e[31m LSN不需要prepare或备份间隔期间无数据变化 e[m" #红色
    echo "*****************************************"
    
    
    
    fi 
    
    
    echo
    echo "Prepare:增量备份集$i........"
    echo "*****************************"
    $INNOBACKUPEX_PATH --defaults-file=$MY_CNF --apply-log --redo-only --use-memory=$MEMORY $FULLBACKUP --incremental-dir=$PARENT_DIR/$FULL/$i > $TMP_LOG 2>&1
    check_innobackupex_fail
    
    ######判断LSN
    check_full_lastlsn=$FULLBACKUP/xtrabackup_checkpoints
       
    fetch_full_lastlsn=`grep -i "^last_lsn" ${check_full_lastlsn} |cut -d = -f 2`
    echo "完全备份当前的LSN:${fetch_full_lastlsn}"
    
    
    else
    error "未知的备份类型"
    fi
    else 
    echo "查找增量备份文件完成."
    check_full_lastlsn=$FULLBACKUP/xtrabackup_checkpoints
       
    fetch_full_lastlsn=`grep -i "^last_lsn" ${check_full_lastlsn} |cut -d = -f 2`
    echo -e "e[31m -------------------------------------------- e[m" #红色
    echo -e "e[31m 完全备份最终的LSN:${fetch_full_lastlsn} e[m" #红色
    echo -e "e[31m -------------------------------------------- e[m" #红色
    break
    fi
    fi
    done
    
    
    fi
    ################判断还原部分增量备份还是所有增量备份################
    
    
    
    fi
    
    
    
    
    echo 
    echo "prepare:完整备份以及回滚那些未提交的事务..........."
    $INNOBACKUPEX_PATH --defaults-file=$MY_CNF --apply-log --use-memory=$MEMORY $FULLBACKUP > $TMP_LOG 2>&1
    check_innobackupex_fail
    
    
    
    
    echo "*****************************"
    echo "数据库还原中 ...请稍等"
    echo "*****************************"
    
    
    $INNOBACKUPEX_PATH --defaults-file=$MY_CNF --copy-back $FULLBACKUP > $TMP_LOG 2>&1
    check_innobackupex_fail
    
    
      
    rm -f $TMP_LOG
    echo "1.恭喜,还原成功!."
    echo "*****************************"
    
    
    
    
    #修改目录权限
    echo "修改mysql目录的权限."
    mysqlcnf="/data/mysql/my.cnf"
    mysqldatadir=`grep -i "^basedir" $mysqlcnf |cut -d = -f 2`
    `echo 'chown -R mysql:mysql' ${mysqldatadir}`
    echo "2.权限修改成功!"
    echo "*****************************"
    
    
    
    
    #自动启动mysql
    
    
    INIT_NUM=1
    if [ ! -x $MYSQLD_SAFE ]; then
      echo "mysql安装时启动文件未安装到$MYSQLD_SAFE或无执行权限"
      exit 1  #0是执行成功,1是执行不成功
    else
    echo "启动本机mysql端口为:$MYSQL_PORT的服务"
    $MYSQLD_SAFE --defaults-file=$MY_CNF  > /dev/null &
    while  [ $INIT_NUM  -le 10 ]
          do
            PORTNUM=`netstat -lnt|grep ${MYSQL_PORT}|wc -l`
            echo "mysql启动中....请稍等..."
            sleep 10
            if [ $PORTNUM = 1  ];
            then
    echo -e "e[32m mysql                                      ****启动成功**** e[m"
            exit 0
            fi 
            INIT_NUM=$(($INIT_NUM +1))
          done
    echo -e "e[31m mysql启动失败或启动时间过长,请检查错误日志 `echo 'cat ' ${ERRORLOG}` e[m"
    echo "*****************************************"
    exit 0
    fi
    
    
    
    
    
    
    
    
    END_RESTORE_TIME=`date +%F' '%T' '%w`
    echo "数据库还原完成于: $END_RESTORE_TIME"
    exit 0
    
    
    
    
    
    
    
    
    
    
    ************************************************************************************************
    执行结果:
    ************************************************************************************************
     
    # ./restore.sh /backup/incre/ 
    输入截止增量备份名[默认所有]:2015-04-10_14-10-49
    
    
    输入截止增量备份名为:2015-04-10_14-10-49
    ----------------------------
    
    
    ./restore.sh: MySQL还原脚本
    数据库还原开始于: 2015-04-10 14:24:51 5
    
    
    Prepare:完整备份...........
    *****************************
    还原的指定增量目录文件2015-04-10_14-10-49的纪元时间为:1428646269
    还原将从全备2015-04-10_14-05-40开始,到增量2015-04-10_14-10-49结束.
    
    
    完全备份的LSN: 344693290 
    增量备份的LSN: 413297865 
    Prepare:增量备份集2015-04-10_14-08-19........
    *****************************
    完全备份当前的LSN: 413297865
    还原将从全备2015-04-10_14-05-40开始,到增量2015-04-10_14-10-49结束.
    
    
    完全备份的LSN: 413297865 
    增量备份的LSN: 481905295 
    Prepare:增量备份集2015-04-10_14-09-07........
    *****************************
    完全备份当前的LSN: 481905295
    还原将从全备2015-04-10_14-05-40开始,到增量2015-04-10_14-10-49结束.
    
    
    完全备份的LSN: 481905295 
    增量备份的LSN: 550515490 
    Prepare:增量备份集2015-04-10_14-10-49........
    *****************************
    完全备份当前的LSN: 550515490
    查找增量备份文件完成.
     -------------------------------------------- 
     完全备份最终的LSN: 550515490 
     -------------------------------------------- 
    
    
    prepare:完整备份以及回滚那些未提交的事务...........
    *****************************
    数据库还原中 ...请稍等
    *****************************
    1.恭喜,还原成功!.
    *****************************
    修改mysql目录的权限.
    2.权限修改成功!
    *****************************
    启动本机mysql端口为:3306的服务
    mysql启动中....请稍等...
    mysql启动中....请稍等...
    mysql启动中....请稍等...
     mysql                                      ****启动成功****  
    
  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    redis被攻击,怎么预防
    Redis3.2.12单节点安装
    Linux安装Redis、后台运行、系统自启动
    Redis 密码设置和查看密码
    Redis protected-mode属性解读
    SpringCloud(9)----mysql实现配置中心
    SpringCloud(8)----zuul权限校验、接口限流
  • 原文地址:https://www.cnblogs.com/smail-bao/p/6094047.html
Copyright © 2011-2022 走看看