#!/bin/sh
##################
#author:rrhelei@126.com#
##################
#xtrabackup2.1.8
# 使用方法:
# ./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=/databackup # 你的备份主目录
FULLBACKUP_DIR=$BACKUP_DIR/full # 全库备份的目录
INCRBACKUP_DIR=$BACKUP_DIR/incre # 增量备份的目录
MEMORY=1024M # 还原的时候使用的内存限制数
ERRORLOG=`grep-i "^log-error" $MY_CNF |cut -d = -f 2`
MYSQLD_SAFE=/usr/local/mysql/bin/mysqld_safe
MYSQL_PORT=3306
 
 
 
 
 #############################################################################
 
 
 #显示错误
 
 
#############################################################################
 
 
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[31mNOTE:------------------------------------------.\e[m" #红色
echo -e "\e[31m mysql处于运行状态,请关闭mysql. \e[m" #红色
echo -e "\e[31mNOTE:------------------------------------------.\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\n" | sort -n `;
do
 
 
#判断最新全备的lsn
#check_full_file=`find$FULLBACKUP/ -mindepth 1 -maxdepth 1 -type d -printf "%P\n" | 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\n" |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\n" | sort -n `;
do
#判断for循环取到的文件名是否为输入的文件名,如果是则停止循环
if ["$i" =  "$ipname" ];then
break;
else
f01=`stat-c=%Z  $PARENT_DIR/$FULL/$i |cut -d = -f2`
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\n" | 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\n" |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="/etc/my.cnf"
 mysqldatadir=`grep -i "^datadir"$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

参考:

http://blog.itpub.net/29114615/viewspace-1408347

http://blog.csdn.net/yangzhawen/article/details/44857097

http://www.2cto.com/database/201504/388993.html

本文出自 “岁伏” 博客,请务必保留此出处http://suifu.blog.51cto.com/9167728/1758032

MySQL XtraBackup自动恢复脚本的更多相关文章

  1. MySQL binlog 自动备份脚本

    MySQL binlog 自动备份脚本 1 利用shell进行备份 #!/bin/sh #mysql binlog backup script /usr/local/mysql/bin/mysqlad ...

  2. mysql xtrabackup 备份恢复实现,mysql命令备份数据库,打包压缩数据库

    简介 Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具.特点: (1)备份过程快速.可靠 ...

  3. mysql数据库自动备份脚本

    #!/bin/bash #功能说明:本功能用于备份mysql数据库 #编写日期:2018/05/17 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin ...

  4. MySQL binlog 自动清理脚本

    # vim /data/scripts/delete_mysql_binlog.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  5. mysql+keepalived主从切换脚本 转

    Keepalived MySQL故障自动切换脚本   MySQL架构为master-slave(主从),master故障自动切换到slave上.当然也可以设置为双master,但这里有个弊端:就是当主 ...

  6. Xtrabackup原理及使用innobackupex进行MySQL数据库备份恢复

    Xtrabackup是由percona提供的mysql数据库备份工具,据官方介绍,这也是世界上惟一一款开源的能够对innodb和xtradb数据库进行热备的工具. Xtrabackup中主要包含两个工 ...

  7. MariaDB/MySQL备份和恢复(三):xtrabackup用法和原理详述

    本文目录: 1.安装xtrabackup 2.备份锁 3.xtrabackup备份原理说明 3.1 备份过程(backup阶段) 3.2 准备过程(preparing阶段) 3.3 恢复过程(copy ...

  8. mysql 自动备份和nginx自动安装脚本

    一.自动备份Mysql脚本: 如下脚本为mysql自动备份脚本,仅供参考,可以根据实际情况修改. #!/bin/sh #auto backup mysql #wugk #Define PATH定义变量 ...

  9. Mysql 自动备份脚本

    转自: Mysql 自动备份脚本2 - - ITeye技术网站http://kangh.iteye.com/blog/2309091 备份方案: 备份主机:192.168.10.11 数据库服务器:1 ...

随机推荐

  1. Android程序两种退出的方法

    两种程序退出的方法: Context的finish()方法: android.os.Process的killProcess()方法:(当程序isRegistered()失败,说明程序被修改过,调用ki ...

  2. Ceph RBD CephFS 存储

    Ceph RBD  CephFS 存储 环境准备: (这里只做基础测试, ceph-manager , ceph-mon, ceph-osd 一共三台) 10.6.0.140 = ceph-manag ...

  3. HTML之禁止输入文本

    一个文本框,禁止输入文本有2个方式,一个是利用readonly ,一个是利用 disabled. 那么两者虽然目的都可以达到,但是从表现上来看disabled会显得更加的直观,为什么这么说. 请看截图 ...

  4. JAVA基础--方法的重写overwrite 和 重载overload

    重写 overwrite或者override: 相同的方法名称, 参数列表和返回类型 重载overload: 方法有相同的名字, 但是参数不同 (参数个数不同, 参数类型不同, 其中一个不同即可), ...

  5. Java虚拟机中的内存分配

    java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途以及创建和销毁的时间. 栈:存放的是局部变量,包括:1.用来保存基本数据类型的值:2.保存类 ...

  6. vim 配置快捷以使复制可用

    "设置快捷以使用xshell的复制 let g_copy_mode = function! CopyToggle() let g:g_copy_mode = set mouse=c set ...

  7. 省市区三级联动插件:app-jquery-cityselect.js

    (function ($) { $.fn.cityselect = function (options) { var settings = $.extend ({}, options); this.e ...

  8. Codeforces#363 Div2

    A题: 题意:给定一些数,给定一些往左走和往右走的操作,问是否能够相遇,如果相遇请求出相遇时间 分析:对于相邻两个数,如果大的往左,小的往右就能够相遇,否则不能相遇,在求出所有相遇当中的第一次相遇即可 ...

  9. 二、HDFS学习

    Hadoop Distributed File System 简称HDFS 一.HDFS设计目标      1.支持海量的数据,硬件错误是常态,因此需要 ,就是备份     2.一次写多次读      ...

  10. HUST 1371 Emergency relief

    状态压缩. 每一个人所需的物品对应一个数字,统计一个每个数字有几个.每一种提供物品的状态也对应一个数字,然后暴力判断. #include<cstdio> #include<cstri ...