原文转自:

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\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 ****启动成功****

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

  1. [svc]mysql备份恢复及常用命令

    如何实现mysql读写分离 1.通过程序实现读写分类(性能 效率最佳) php和java都可以通过设置多个连接文件轻松实现对db的读写分离,即当select时,就去连读库的连接文件,当update,i ...

  2. 解析binlog生成MySQL回滚脚本

    如果数据库误操作想恢复数据.可以试试下面这个脚本.前提是执行DML操作. #!/bin/env python #coding:utf-8 #Author: Hogan #Descript : 解析bi ...

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

    明: 我这里要把MySql数据库存放目录/var/lib/mysql下面的pw85数据库备份到/home/mysql_data里面,并且保存为mysqldata_bak_2012_04_11.tar. ...

  4. MySQL的启动脚本

    MySQL的启动脚本#!/bin/bashmysql_port=3308mysql_username="admin"mysql_password="password&qu ...

  5. linux shell:mysql bin_log定期清理脚本

    需求: 1.自动处理mysql bin日志脚本 2.输出可读log 3.保留1周的日志 4.对所有数据库统一处理.   实现过程描述:   思路:两种方式实现 1.mysql目录通过ls获取bin日志 ...

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

    [分享]运维分享一一阿里云linux系统mysql密码修改脚本       大象吃豆子 级别: 小白 发帖 12 云币 27 加关注 写私信   只看楼主 更多操作楼主  发表于: 2014-09-3 ...

  7. Windows下MySQL数据库备份脚本(一)

    说明: MySQL数据库安装目录:C:\Program Files\MySQL\MySQL Server 5.0 MySQL数据库存放目录:C:\Program Files\MySQL\MySQL S ...

  8. Windows下MySQL数据库备份脚本(二)

    说明: MySQL数据库安装目录:C:\Program Files\MySQL\MySQL Server 5.0 MySQL数据库存放目录:C:\Program Files\MySQL\MySQL S ...

  9. Mysql 自动备份脚本

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

随机推荐

  1. USACO1.1Broken Necklace[环状DP作死]

    题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 n=29 的二个例子: 第一和第二个珠子在图片中已经被作记号. 图片 A ...

  2. jquery添加光棒效果的各种方式以及简单动画复杂动画

    过滤器.绑定事件.动画   一.基本过滤器 语法 描述 返回值 :first 选取第一个元素 单个元素 :last 选取最后一个元素 单个元素 :not(selector) 选取去除所有与给定选择器匹 ...

  3. AC日记——字符替换 openjudge 1.7 08

    08:字符替换 总时间限制:  1000ms 内存限制:  65536kB 描述 把一个字符串中特定的字符全部用给定的字符替换,得到一个新的字符串. 输入 只有一行,由一个字符串和两个字符组成,中间用 ...

  4. java 25 - 4 网络编程之 UDP协议传输的代码优化

    UDP协议的输出端: /* UDP发送数据: A:创建Socket发送端对象 B:创建数据报包(把数据打包) C:调用Socket对象发送数据报包 D:释放资源(底层是IO流) */ public c ...

  5. fragment的切换(解决REPLACE的低效)

    在项目中切换Fragment,一直都是用replace()方法来替换Fragment.但是这样做有一个问题,每次切换的时候Fragment都会重新实列化,重新加载一次数据,这样做会非常消耗性能用用户的 ...

  6. avalon.js路由

    之前自己写了一个AJAX加载页面的方法:有时候一个页面里面会分区域加载不同的东西(div,html),但是IE的回退按钮,就失去任何意义了: 这两天研究了一下avalon.js的路由: 需要准备: 1 ...

  7. android小游戏 飞机躲子弹

    最近android老师让每人写一个小东西,因为之前学awt时写过一个java版的飞机躲子弹,所以这次想写成android版的. 文件直接导入就行http://files.cnblogs.com/fil ...

  8. 关于onbeforeunload的一些想法

    页面在关闭前会有onbeforeUnload事件,来询问用户是否要关闭这个页面OR选项卡 浏览器的F5刷新为按下F5----onbeforeUnload----onunload----onload; ...

  9. noi1696 逆波兰表达式

    1696:逆波兰表达式 http://noi.openjudge.cn/ch0303/1696/ 总时间限制:  1000ms 内存限制:  65536kB 描述 逆波兰表达式是一种把运算符前置的算术 ...

  10. redis 学习笔记(3)-master/slave(主/从模式)

    类似mysql的master-slave模式一样,redis的master-slave可以提升系统的可用性,master节点写入cache后,会自动同步到slave上. 环境: master node ...