如果不小心删除了一批记录,并提交了,在oracle中可以使用闪回查询,闪回版本查询获取丢失的数据,在mysql中没有很好的办法,不过有一种方式是读取二进制文件
前提条件:
1,开启二进制
查看并开启show variables like '%log_bin%';
如果没有开启,设置加入参数log-bin=mysql-binlog
2,日志格式为ROW
binlog_format=ROW
1,获取二进制日志内容
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');
前提条件:
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');