赞
踩
场景是这样子的:
如果有人不小心删了数据库,怎么办?
主从?恐怕不行,数据实时同步,备库的数据也被删了。
那从库延迟同步,如何?嗯嗯,应该可以。那问题来了。如果延迟同步的情况下,发生数据库误删除,运维人员赶紧切到从库上,终究是能尽快的恢复业务,只是有一部分数据会丢失,那么怎样让服务继续运行的情况下,补回那一部分丢失的数据呢?
这种情况下,我的脚本就派上用场了!
我的思路是这样子的:
忘记一件事,强调一下,在切换到从库之前,请将关键表中的主键如果是自增ID,那请将自增ID向后增大一定数值,这样是为了让丢失的数据能补回!
alter table users AUTO_INCREMENT=xxxxx; 这个语句应该是可帮助你的.
有些请款,可能需要暂时关闭外键set foreign_key_checks=0;
言归正传的讲,我们当时的场景是这样的,我们用的阿里云的RDS,所以恢复之前还得先下载binlog日志。
所以准备条件就这样的:
1. 需要在阿里云上创建一个子账号,
2. 需要aliyuncli工具调用RDS接口,得到binlog日志内网下载地址。
3. 需要在灾备RDS上创建一个binlog的账号
4. 需要一个下载binlog日志并能解包的脚本
5. 需要一个将binlog日志转换成可用sql的脚本
开始干活写脚本:
aliyuncli rds DescribeBinlogFiles--DBInstanceId rdsid --StartTime 2017-02-15T14:00:00Z --EndTime2017-02-15T14:30:00Z
脚本:
- #!/usr/bin/python
- #coding:utf-8
- import os,sys
- import json
- import time
-
- def get_url():
- #urlContent = os.popen("aliyuncli rds DescribeBinlogFiles--DBInstanceId rdsid --StartTime 2017-02-17T10:00:00Z --EndTime2017-02-17T12:00:00Z")
- DBId = ''
- starttime = '2017-02-20 09:00:00'
- endtime = '2017-02-20 12:00:00'
- starttime = conv_time(starttime,8)
- endtime = conv_time(endtime,8)
-
-
- urlContent = os.popen("aliyuncli rds DescribeBinlogFiles--DBInstanceId %s --StartTime %s --EndTime%s"%(DBId,starttime,endtime)).read()
- urlContent = json.loads(urlContent)
- urlfile = file('urlfile','w+')
- for url in urlContent['Items']['BinLogFile']:
- if url['HostInstanceID'] == 1669377:
- print url
- urlfile.write('%s\n'%url["IntranetDownloadLink"])
- urlfile.close()
-
-
- def conv_time(n_time,n=8):
- s_time = time.mktime(time.strptime(n_time,"%Y-%m-%d%H:%M:%S"))
- addtime = 3600 * n
- f_time = s_time -addtime
- n_time =time.strftime("%Y-%m-%dT%H:%M:%SZ",time.localtime(f_time))
- return n_time
-
- if __name__ == '__main__':
- get_url()
#!/bin/bash
wget -c -i /opt/binlog/rds_binlog/urlfile-P /opt/binlog/rds_tar
if [ $? != 0 ];then
echo "wget error"
fi
cd /opt/binlog/rds_sql
ls /opt/binlog/rds_tar/*.tar* |xargs -n1tar xvf
脚本思路:
1. 利用binlog工具进行转换成sql,但是sql有些需要去转换成我们可识别的形式
2. 转换sql,查询mysql的表字段,利用正则表达式匹配insert,delete,update的语句,将所有@1这种类型的字段进行转换
- #encoding:UTF-8
- #!/usr/bin/python
-
- import os,sys,re,getopt
- import MySQLdb
- import time,datetime
-
- host =''
- user = ''
- password = ''
- port = 3306
- start_datetime = ''
- stop_datetime = ''
- start_position = ''
- stop_position = ''
- database = ''
- mysqlbinlog_bin = 'mysqlbinlog -v'
- binlog = ''
- fileContent = ''
- output='rollback.sql'
- only_primary = 1
- tmp_binlog_file ="tmp_binlog_file"
-
-
- field_list = ''
-
- #----------------------------------------------------------------------------------------
- # 功能:获取参数,生成相应的binlog解析文件
- #----------------------------------------------------------------------------------------
- def getopts_parse_binlog():
- globalhost
- globaluser
- globalpassword
- globalport
- globalfileContent
- globaloutput
- globalbinlog
- globalstart_datetime
- globalstop_datetime
- globalstart_position
- globalstop_position
- globaldatabase
- globalonly_primary
- try:
- options,args= getopt.getopt(sys.argv[1:],"f:o:h:u:p:P:d:",["help","binlog=","output=","host=","user=",\
- "password=","port=","start-datetime=","stop-datetime=","start-position=","stop-position=","database=","only-primary="])
- exceptgetopt.GetoptError:
- print"参数输入有误!!!"
- options= []
- ifoptions == [] or options[0][0] in ("--help"): #如果输入错误或者--help则提示帮助信息
- usage() #显示帮助信息
- sys.exit()
- print"正在获取参数......"
- printoptions
- forname, value in options:
- ifname == "-f" or name == "--binlog":
- binlog= value
- elifname == "-o" or name == "--output":
- output= value
- elifname == "-h" or name == "--host":
- host= value
- elifname == "-u" or name == "--user":
- user= value
- elifname == "-p" or name == "--password":
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。