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
#[email protected]
#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\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 = -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\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="/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                                      ****启动成功****
时间: 2024-11-05 13:47:36

MySQL的恢复脚本的相关文章

Ubuntu Server下MySql数据库备份脚本代码

明: 我这里要把MySql数据库存放目录/var/lib/mysql下面的pw85数据库备份到/home/mysql_data里面,并且保存为mysqldata_bak_2012_04_11.tar.gz的压缩文件格式(2012_04_11是指备份执行时当天的日期), 最后只保留最近7天的备份. 实现步骤: 1.创建保存备份文件的目录:/home/mysql_datacd /home #进入目录mkdir mysql_data #创建目录2.创建备份脚本文件:/home/mysql_data/m

MySQL数据库恢复(使用mysqlbinlog命令)

MySQL数据库恢复(使用mysqlbinlog命令) 1:开启binlog日志记录 修改mysql配置文件mysql.ini,在[mysqld]节点下添加 复制代码代码如下: # log-bin log-bin = E:/log/logbin.log 路径中不要包含中文和空格.重启mysql服务.通过命令行停止和启动mysql服务 复制代码代码如下: c:\>net stop mysql; c:\>net start mysql; 进入命令行进入mysql并查看二进制日志是否已经启动 Sql

企业实战:mysql5.6数据库备份、恢复脚本

一.mysql数据库备份脚本 备份脚本1: [[email protected] scripts]# vim elab_fenku_backup.sh #!/bin/sh #create at 2018-01-08 #author oldboy #qq 88888 echo "--------------------------ychfq:`date +%F-%H`--------------------------" DB_USER="oldboy_bak" DB

mysql数据库备份脚本

自动备份Mysql脚本: 如下脚本为mysql自动备份脚本,仅供参考,可以根据实际情况修改. #!/bin/sh #auto backup mysql #20170329 #Define PATH定义变量 BAKDIR=/data/backup/mysql/`date +%Y-%m-%d` MYSQLDB=webapp MYSQLPW=backup MYSQLUSR=backup #must use root user run scripts 必须使用root用户运行,$UID为系统变量 if

mysql自动安装脚本

为适应自己工作习惯和需要,花一点时间写了一个mysql自动安装脚本,供大家参考学习. 注意: 1.需要先安装cmake 2.数据库版本需要在第二步安装mysql时修改 3.该脚本是以root用户安装并启动 脚本内容如下: ######################################################################## #mysql自动安装脚本,其中变量/mysql_v_dir/和/port/可根据实际需要修改    # #执行脚本命令:sh mys

MySQL备份数据库脚本

Windows @echo offmysqldump --add-drop-database --add-drop-table -u root -p123456 dbname > d:\db_backup\%date:~0,4%-%date:~5,2%-%date:~8,2%_%time:~0,2%-%time:~3,2%-%time:~6,2%_dbname.sql Linux #!/bin/shcd /usr/binDATE=`date +%Y-%m-%d`# 备份dbname数据库/usr

MySQL崩溃恢复过程常见错误分析

最近在和一个同事争论MySQL崩溃恢复中的一些常见错误时出现了一些分歧,他认为一些参数的设置会导致MySQL出现崩溃后恢复不起来的问题,但对此,我却不认同,虽然一些参数的设定会导致数据丢失,但应该不会引起数据库崩溃之后无法恢复的情况,因此,就想整理出MySQL崩溃恢复的过程来加深学习! 图一 mysql WAL过程 在正常情况下,数据写入会先写入redo_buffer_pool,然后在写入redo_log_file,这中间如果由于参数设置不当,可能会发生丢失,但不影响主机的崩溃恢复,但有以下两种

linux系统mysql密码修改脚本

编写了一个适用于阿里云linux系统 mysql密码修改脚本,使用阿里云提供的一键安装包配置后,如果account.log文件删除,并且忘记mysql密码时,可以通过脚本来重置mysql密码. 附:一键环境安装包:http://help.aliyun.com/view/11108189_13435438.html?spm=5176.7224445.1997283057.5.RLNWqv 下载地址: gbk版:默认使用这个版本 wget http://jinxiang.oss-cn-hangzho

[分享]运维分享一一阿里云linux系统mysql密码修改脚本

[分享]运维分享一一阿里云linux系统mysql密码修改脚本     大象吃豆子 级别: 小白 发帖 12 云币 27 加关注 写私信 只看楼主 更多操作楼主  发表于: 2014-09-30 编写了一个适用于阿里云linux系统 mysql密码修改脚本,使用阿里云提供的一键安装包配置后,如果account.log文件删除,并且忘记mysql密码时,可以通过脚本来重置mysql密码. 附:一键环境安装包:http://help.aliyun.com/view/11108189_13435438