读取binlog的delete记录

来源:互联网 发布:软件测试pdf 编辑:程序博客网 时间:2024/05/21 19:50
如果不小心删除了一批记录,并提交了,在oracle中可以使用闪回查询,闪回版本查询获取丢失的数据,在mysql中没有很好的办法,不过有一种方式是读取二进制文件
前提条件:
1,开启二进制
   查看并开启show variables like '%log_bin%';
   如果没有开启,设置加入参数log-bin=mysql-binlog
2,日志格式为ROW
   binlog_format=ROW

1,获取二进制日志内容

  mysqlbinlog --start-datetime='2016-12-20 09:27:54' --stop-datetime='2016-12-20 09:30:40' -vv mysql-binlog.000001 >/root/1.log       --  制定库名的,-d  db1

注意:

 尽量不要查看正在写入的日志文件;这里是行格式,加了-vv

 部分内容:
SET @@session.time_zone='SYSTEM'/*!*/;
SIlYWBMKAAAANQAAAHIGAAAAAG4AAAAAAAEABXRlc3QxAAR0ZXN0AAMDDxIDHgAAB0gAHxo=
SIlYWCAKAAAANAAAAKYGAAAAAG4AAAAAAAEAAgAD//gCAAAABue+juWbvZmbKJcV+bhyjQ==
'/*!*/;
### DELETE FROM `test1`.`test`
### WHERE
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
###   @2='美国' /* VARSTRING(30) meta=30 nullable=1 is_null=0 */
###   @3='2016-12-20 09:28:21' /* DATETIME(0) meta=0 nullable=1 is_null=0 */
# at 1702
#161220  9:28:40 server id 10  end_log_pos 1733 CRC32 0x1f21e110        Xid = 30
COMMIT/*!*/;

2,使用python分析,脚本如下,摘录网上

#!/bin/env python
# -*- encoding: utf-8 -*-
def read_binlog(file,column_num):
    f=open(file)
    num = '@'+str(column_num)
    while True:
        lines = f.readline()
        if lines.strip()[0:3] == '###':
            lines=lines.split(' ',3)
            if lines[1] == 'DELETE' and lines[2] =='FROM':           #该部分替换Delete为Insert
                lines[1] = "INSERT"
                lines[2] = 'INTO'
                lines[-1] = lines[-1].strip()
            if lines[1].strip() == 'WHERE':
                lines[1] = 'VALUES ('
            if  ''.join(lines).find('@') <> -1 and lines[3].split('=',1)[0] <> num:          #num为列数,要是小于最大的列数
                print ''.join(lines[3])
                lines[3] = lines[3].split('=',1)[-1].strip()
                #print 'test2---'.join(lines[3])
                if lines[3].strip('\'').strip().find('\'') <> -1:
                    lines[3] = lines[3].split('/*')[0].strip('\'').strip().strip('\'').replace('\\','').replace('\'','\\\'')  #这里过滤掉转义的字符串
                    lines[3] = '\'' + lines[3] + '\','
                elif lines[3].find('INT meta') <> -1:                #过滤Int类型的字段为负数后带的(),正数不受影响
                    lines[3] = lines[3].split('/*')[0].strip()
                    lines[3] = lines[3].split()[0] + ','
                elif lines[3].find('NULL') <> -1:
                    lines[3] = lines[3].split('/*')[0].strip()
                    lines[3] = lines[3] + ','
                else:
                    lines[3] = lines[3].split('/*')[0].strip('\'').strip().strip('\'').replace('\\','').replace('\'','\\\'')  #这里过滤掉转义的字符串
                    lines[3] = '\'' + lines[3].strip('\''' ') + '\','
            if  ''.join(lines).find('@') <> -1 and lines[3].split('=',1)[0] == num:          #num为列数,要是小于最大的列数);
                lines[3] = lines[3].split('=',1)[-1].strip()
                if lines[3].find('\'') <> -1:
                    lines[3] = lines[3].split('/*')[0].strip('\'').strip().strip('\'').replace('\\','').replace('\'','\\\'')  #同上
                    lines[3] = '\'' + lines[3] + '\');'
                elif lines[3].find('INT meta') <> -1:                #同上
                    lines[3] = lines[3].split('/*')[0].strip()
                    lines[3] = lines[3].split(' ')[0] + ');'
                elif lines[3].find('NULL') <> -1:
                    lines[3] = lines[3].split('/*')[0].strip()
                    lines[3] = lines[3] + ');'
                else:
                    lines[3] = lines[3].split('/*')[0].strip('\'').strip().strip('\'').replace('\\','').replace('\'','\\\'')  #同上
                    lines[3] = '\'' + lines[3].strip('\''' ') + '\');'
            print ' '.join(lines[1:])
        if lines == '':
            break
if __name__ == '__main__':
    import sys
    read_binlog(sys.argv[1],sys.argv[2])

调用python my.py 1.txt 3 > 1.sql
内容为:
INSERT INTO `test1`.`test`
VALUES (
  2,
  '美国',
  '2016-12-20 09:28:21');
0 0
原创粉丝点击