导出某个日期开始的MySQL_编写指定日期导出mysqlbinlog为.sql文件的程序

本文介绍了一个bash脚本,该脚本根据用户输入的日期范围,从MySQL binlog中导出指定时间跨度的SQL语句到.sql文件。脚本首先读取MySQL配置文件获取binlog位置,然后找到这段时间内的binlog文件,根据用户输入的数据库名选择导出所有库还是特定库,并将结果追加到.sql文件中。
摘要由CSDN通过智能技术生成

一,首先,我介绍一下脚本的功能。

1,如图,画红线的地方为输入框

0c5bd1dc0cbce438d869f699573a5a0f.png

2,程序会提示您只能恢复的数据的时间段。  如图 等号线中间的提示

3,提示输入想到恢复的起始时间  如 : 2011-03-10 12:00:00

4,提示输入想到恢复的结束时间  如 : 2011-03-10 13:00:00

5,提示输入想到恢复的库文件,不填此项为全选。要恢复某个库直接填写库名

第一例中我们先不填库名,刚运行结果如上图所示,我们看一下运行后的情况

6,如果不填库名的话,程序运行后,会直接在根目录下生成一个all.sql文件,里面记录里了,起始时间到结束时间的所有数据库的操作,如下图所示

cf0b42329014f3a1139f0b237ec4da24.png

7 恢复数据到数据库

#mysql -p密码 

第二例中,我们来一个带库的,我们来看看运行后的结果 (如下图)

8e07194e78c9fd103b608ce2fe56b798.png

1,我们时间选择和上面一个,但是在提示输入库的时候,我们填入 mysql 库。 程序执行成功后会在根目录下生成一个 库名。Sql的文件,些例中,刚在根目录 下生成一个 mysql.sql的文件,我们看看这个文件里有什么 如下图:

21e30994abeb93f9e07614fb8703ae8e.png

里面操作不多,我们来把这个文件导入到数据库里

# mysql -p密码  mysql 

导入完成后,就完成了所有的操作了。

那么,接下来,我们来看看这个 datarecover.sh 里到底有什么,还有他是怎么工作的呢?

我先把里面的程序贴出来,看一下,如下

#! /bin/bash

_binlogdir=`cat /etc/my.cnf|grep log-bin|awk -F = '{print $2}'|sed 's/ //g'`

_fristbinlog=`ls -r $_binlogdir* |tail -1`

_lastbinlog=`ls $_binlogdir* |tail -2|grep -v index`

_fristbinlogtime=`stat "$_fristbinlog" |grep Modify|awk -F . '{print $1}'|awk -F Modify: '{print $2}'`

_lastbinlogtime=`stat "$_lastbinlog"  |grep Modify|awk -F . '{print $1}'|awk -F Modify: '{print $2}'`

echo "================================================================"

echo " 此程序只能导出 $_fristbinlogtime - $_lastbinlogtime 的sql语句  "

echo "================================================================"

read -p "请输入开始时间 Please enter begian time (such as 2010-01-01 09:23:01) :" fristbegiantime

read -p "请输入结束时间 Please enter over  time (such as 2010-10-10 09:23:01) :" fristovertime

read -p "请输入要导出的库,不填此项为全选 :" dbname

_fristNo=`echo $_fristbinlog|awk -F . '{print $2}'`

_lastNo=`echo $_lastbinlog|awk -F . '{print $2}'`

begiantime=`date -d "$fristbegiantime" +%s`

overtime=`date -d "$fristovertime" +%s`

for No in `seq -f %06g $_fristNo $_lastNo`

do

_alltime=`stat $_binlogdir.$No|grep Modify|awk -F . '{print $1}'|awk -F Modify: '{print $2}'`

_alltime=`date -d "$_alltime" +%s`

_begchazhi=$(($begiantime - $_alltime ))

_lachazhi=$(($overtime - $_alltime))

if [ $_begchazhi -gt 0 ]&& [ $_begchazhi -lt 3600 ];then

_begianNo=$No

fi

if [ $_lachazhi -gt 0 ]&& [ $_lachazhi -lt 3600 ];then

_lastNo=$No

fi

done

if [ -z $dbname  ];then

for No in `seq -f %06g $_begianNo $_lastNo`

do

mysqlbinlog --start-datetime="$fristbegiantime" --stop-datetime="$fristovertime" $_binlogdir.$No  >>/all.sql

done

else

for No in `seq  -f %06g $_begianNo $_lastNo`

do

mysqlbinlog --start-datetime="$fristbegiantime" --stop-datetime="$fristovertime" --database $dbname  $_binlogdir.$No >>/$dbname.sql

done

fi

代码贴出来了,下面我来解释一下,他是如何工作的,跟往常一下,对每一句代码进行解释(全比较乱,慢慢看)

#! /bin/bash

_binlogdir=`cat /etc/my.cnf|grep log-bin|awk -F = '{print $2}'|sed 's/ //g'`

# 从mysql配置文件里获取 binlog 的存放位置,及binlog的前缀

_fristbinlog=`ls -r $_binlogdir* |tail -1`

#在binlog存放目录里,找出最早时间的binlog文件,并附给_fristbinlog变量

_lastbinlog=`ls $_binlogdir* |tail -2|grep -v index`

#在binlog存放目录里,找出最后时间的binlog文件,并附给_lastbinlog变量

_fristbinlogtime=`stat "$_fristbinlog" |grep Modify|awk -F . '{print $1}'|awk -F Modify: '{print $2}'`

_lastbinlogtime=`stat "$_lastbinlog"  |grep Modify|awk -F . '{print $1}'|awk -F Modify: '{print $2}'`

#分别显示出最早的和最晚的binlog文件的时间,分别附给 _fristbinlogtime 和 _lastbinlogtime 变量

echo "================================================================"

echo " 此程序只能导出 $_fristbinlogtime - $_lastbinlogtime 的sql语句  "

echo "================================================================"

#echo 出三条语句,第一个和最后一个好理解,中间一条语句,将最早和最晚的变量打印出来。组成一话语。

read -p "请输入开始时间 Please enter begian time (such as 2010-01-01 09:23:01) :" fristbegiantime

#提示用户输入开始时间,并把开始时间赋值给 fristbegiantime变量

read -p "请输入结束时间 Please enter over  time (such as 2010-10-10 09:23:01) :" fristovertime

#提示用户输入结束时间,并把结束时间赋值给 fristovertime 变量

read -p "请输入要导出的库,不填此项为全选 :" dbname

#提示用户输入导出的库,并把值赋给 dbname 变量

_fristNo=`echo $_fristbinlog|awk -F . '{print $2}'

# 获取首个binlog。后面的值 ,(注:binlog格式一般为 binlog.000001  binlog.000002 这一句就是获取 000001 这样的值 )

`

_lastNo=`echo $_lastbinlog|awk -F . '{print $2}'`

#获取最后一个binlog . 后面的值

begiantime=`date -d "$fristbegiantime" +%s`

#将提示输入开始的值 ,变成时间戳格式

overtime=`date -d "$fristovertime" +%s`

#将提示输入结束的值 ,变成时间戳格式

for No in `seq -f %06g $_fristNo $_lastNo`

Do

For循环定义:逐个找出开始时间与结束时间最接近的binlog文件,

_alltime=`stat $_binlogdir.$No|grep Modify|awk -F . '{print $1}'|awk -F Modify: '{print $2}'`

#找出变量 $_binlogdir.$No 的创建时间 $_binlogdir.$No 为遍历所有的binlog文件

_alltime=`date -d "$_alltime" +%s`

#将变量$_binlogdir.$No的时间,变成时间戳格式,

_begchazhi=$(($begiantime - $_alltime ))

#将输入的开始时间的时间戳,减掉遍历出的文件时间戳

_lachazhi=$(($overtime - $_alltime))

#将输入的结束时间的时间戳,减掉遍历出的文件时间戳

if [ $_begchazhi -gt 0 ]&& [ $_begchazhi -lt 3600 ];the

_begianNo=$No

Fi

#如果开始时间的时间戳,减掉遍历出的文件时间戳,大于0 小于3600 则把这个值赋_begianNo 变量,即

$_binlogdir$_begianNo 则是提示输入的时间,开始的文件

if [ $_lachazhi -gt 0 ]&& [ $_lachazhi -lt 3600 ];then

_lastNo=$No

Fi

#如果结束时间的时间戳,减掉遍历出的文件时间戳,大于0 小于3600 则把这个值赋_lastNo 变量 ,即

$_binlogdir$_lastNo 则是提示输入的时间,结束的文件

Done

注:前面文章里提到,binlog文件为每隔一个小时刷新一次。转换为时间戳为 3600

到这里,开始和结束的文件都找到了,我们就要开始从开始到结束的文件里导出数据了

if [ -z $dbname  ];then

#我们先判断一开始提示输入的库名,有没有,如果没有的话,我们就直接执行下面的导出所有库操作,有的话,就跳到else后面,执行导出单个库的操作,我们继续往下看。。。

for No in `seq -f %06g $_begianNo $_lastNo`

Do

#这个循环就是导出所有的库,从指定时间开始的文件遍历到指定时间结束的文件,上面的变量要注意,只是  binlog .后面的数定,而不是整个binlog 文件。上面seq 我解释一下: seq -f %06g 这个是seq 打印出的格式,因为binglog .后面都是一个六位数组合,例如000001  000123, 如果不指定 -f %06g的话,就打引出 1  123,前面就没0了,而我们需要保持前面的0.

mysqlbinlog --start-datetime="$fristbegiantime" --stop-datetime="$fristovertime" $_binlogdir.$No  >>/all.sql

#每次执行这个导出语句,并把结果追加到/all.sql里面。 --start-datatime 指定开始时间, --stop-datatime指定结束时间。  $_binlogdir.$No 为每个遍历的文件。

done

else

for No in `seq  -f %06g $_begianNo $_lastNo`

Do

# 好,这个循环就是导出单个库了,如果定义了单个库的话,那我们就执行这一句,指定开始时间,结束时间,库名,

导出到根目录下以库名。Sql命令的文件

mysqlbinlog --start-datetime="$fristbegiantime" --stop-datetime="$fristovertime" --database $dbname  $_binlogdir.$No >>/$dbname.sql

done

Fi

到此就结束了。

总结: 这个脚本功能不大,其实不用这个脚本,就单纯手工操作也很方便,而且这里存在许多bug,比如提示我输入日期时我不写,my.cnf 里面没有定义bin-log ,这都会出现问题,但是跑在我自己的服务器上够了,需要的朋友,可以拷下去,做相应的修改,改成最适合自己的程序。有什么不懂的,可以加我QQ一起讨论:410018348,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值