基于阿里云RDS数据误删除的回滚方案

场景是这样子的:

如果有人不小心删了数据库,怎么办?

       主从?恐怕不行,数据实时同步,备库的数据也被删了。

       那从库延迟同步,如何?嗯嗯,应该可以。那问题来了。如果延迟同步的情况下,发生数据库误删除,运维人员赶紧切到从库上,终究是能尽快的恢复业务,只是有一部分数据会丢失,那么怎样让服务继续运行的情况下,补回那一部分丢失的数据呢?

      这种情况下,我的脚本就派上用场了!


我的思路是这样子的:

     忘记一件事,强调一下,在切换到从库之前,请将关键表中的主键如果是自增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的脚本


开始干活写脚本

1. 利用aliyuncli工具,输入如下命令:

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()



2. 得到的内网地址,放入urlfie文件

 

#!/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



3. 利用python脚本对binlog日志进行转换

  脚本思路:

 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":
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值