Heim > Datenbank > MySQL-Tutorial > 实现MySQL回滚的Python脚本的编写教程_MySQL

实现MySQL回滚的Python脚本的编写教程_MySQL

PHP中文网
Freigeben: 2016-05-27 13:45:48
Original
1564 Leute haben es durchsucht

操作数据库时候难免会因为“大意”而误操作,需要快速恢复的话通过备份来恢复是不太可能的,因为需要还原和binlog差来恢复,等不了,很费时。这里先说明下因为Delete 操作的恢复方法:主要还是通过binlog来进行恢复,前提是binlog_format必须是Row格式,否则只能通过备份来恢复数据了。
方法:

条件:开启Binlog,Format为Row。

步骤:

1.通过MySQL自带工具mysqlbinlog 指定导出操作的记录:

mysqlbinlog 
--no-defaults 
--start-datetime='2012-12-25 14:56:00' 
--stop-datetime='2012-12-25 14:57:00' 
-vv mysql-bin.000001 > /home/zhoujy/restore/binlog.txt
Nach dem Login kopieren

2.数据取出来之后,需要把数据解析反转,原始数据:

### DELETE FROM test.me_info 
### WHERE 
###  @1=2165974 /* INT meta=0 nullable=0 is_null=0 */ 
###  @2='1984:03:17' /* DATE meta=0 nullable=1 is_null=0 */ 
###  @3=NULL /* DATE meta=765 nullable=1 is_null=1 */ 
###  @4=2012-10-25 00:00:00 /* DATETIME meta=0 nullable=0 is_null=0 */ 
###  @5='' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */ 
###  @6=0 /* TINYINT meta=0 nullable=1 is_null=0 */ 
###  @7='' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */ 
###  @8=-1 (4294967295) /* INT meta=0 nullable=1 is_null=0 */ 
###  @9=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */ 
###  @10=NULL /* MEDIUMINT meta=0 nullable=1 is_null=1 */ 
###  @11=2 /* TINYINT meta=0 nullable=1 is_null=0 */ 
###  @12=0 /* TINYINT meta=0 nullable=1 is_null=0 */ 
###  @13='' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */ 
###  @14='' /* VARSTRING(765) meta=765 nullable=1 is_null=0 */ 
###  @15=0 /* MEDIUMINT meta=0 nullable=1 is_null=0 */ 
###  @16=320 /* INT meta=0 nullable=1 is_null=0 */ 
…………………… 
…………………… 
……………………
Nach dem Login kopieren

Row格式的binlog记录的格式如上面所示,需要做的工作就是吧Delete的操作转换成Insert操作,发上面的都是有一定规律的,并且需要注意的是:

1、字段类型 DATETIME 日期。在日志中保存的格式为 @4=2012-10-25 00:00:00,需要将2012-10-25 00:00:00加上引号。

2、负数。在日志中保存的格式为 @1=-1 (4294967295), -2(4294967294),-3(4294967293),需要将()里面的数据去掉,只保留@1=-1。

3、转义字符集。如:'s,\,等。

上面3点清楚之后,可以写一个脚本(水平有限,在提升中,写的不好看):

#!/bin/env python 
# -*- encoding: utf-8 -*- 
#------------------------------------------------------------------------------- 
# Name:    restore.py 
# Purpose:   通过Binlog恢复Delete误操作数据 
# Author:   zhoujy 
# Created:   2012-12-25 
# update:   2012-12-25 
# Copyright:  (c) Mablevi 2012 
# Licence:   zjy 
#------------------------------------------------------------------------------- 
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 &#39;&#39;.join(lines).find(&#39;@&#39;) <> -1 and lines[3].split(&#39;=&#39;,1)[0] <> num:     
      #num为列数,要是小于最大的列数,后面均加, 
        lines[3] = lines[3].split(&#39;=&#39;,1)[-1].strip() 
        if lines[3].strip(&#39;\&#39;&#39;).strip().find(&#39;\&#39;&#39;) <> -1: 
          lines[3] = lines[3].split(&#39;/*&#39;)[0].strip(&#39;\&#39;&#39;).strip().strip(&#39;\&#39;&#39;).replace(&#39;\\&#39;,&#39;&#39;).
          replace(&#39;\&#39;&#39;,&#39;\\\&#39;&#39;) #这里过滤掉转义的字符串 
          lines[3] = &#39;\&#39;&#39; + lines[3] + &#39;\&#39;,&#39; 
        elif lines[3].find(&#39;INT meta&#39;) <> -1:        #过滤Int类型的字段为负数后带的(),正数不受影响 
          lines[3] = lines[3].split(&#39;/*&#39;)[0].strip() 
          lines[3] = lines[3].split()[0] + &#39;,&#39; 
        elif lines[3].find(&#39;NULL&#39;) <> -1: 
          lines[3] = lines[3].split(&#39;/*&#39;)[0].strip() 
          lines[3] = lines[3] + &#39;,&#39; 
        else: 
          lines[3] = lines[3].split(&#39;/*&#39;)[0].strip(&#39;\&#39;&#39;).strip().strip(&#39;\&#39;&#39;).replace(&#39;\\&#39;,&#39;&#39;).
          replace(&#39;\&#39;&#39;,&#39;\\\&#39;&#39;) #这里过滤掉转义的字符串 
          lines[3] = &#39;\&#39;&#39; + lines[3].strip(&#39;\&#39;&#39;&#39; &#39;) + &#39;\&#39;,&#39; 
      if &#39;&#39;.join(lines).find(&#39;@&#39;) <> -1 and lines[3].split(&#39;=&#39;,1)[0] == num:     
      #num为列数,要是小于最大的列数,后面均加); 
        lines[3] = lines[3].split(&#39;=&#39;,1)[-1].strip() 
        if lines[3].find(&#39;\&#39;&#39;) <> -1: 
          lines[3] = lines[3].split(&#39;/*&#39;)[0].strip(&#39;\&#39;&#39;).strip().strip(&#39;\&#39;&#39;).replace(&#39;\\&#39;,&#39;&#39;).
          replace(&#39;\&#39;&#39;,&#39;\\\&#39;&#39;) #同上 
          lines[3] = &#39;\&#39;&#39; + lines[3] + &#39;\&#39;);&#39; 
        elif lines[3].find(&#39;INT meta&#39;) <> -1:        #同上 
          lines[3] = lines[3].split(&#39;/*&#39;)[0].strip() 
          lines[3] = lines[3].split(&#39; &#39;)[0] + &#39;);&#39; 
        elif lines[3].find(&#39;NULL&#39;) <> -1: 
          lines[3] = lines[3].split(&#39;/*&#39;)[0].strip() 
          lines[3] = lines[3] + &#39;);&#39; 
        else: 
          lines[3] = lines[3].split(&#39;/*&#39;)[0].strip(&#39;\&#39;&#39;).strip().strip(&#39;\&#39;&#39;).replace(&#39;\\&#39;,&#39;&#39;).
          replace(&#39;\&#39;&#39;,&#39;\\\&#39;&#39;) #同上 
          lines[3] = &#39;\&#39;&#39; + lines[3].strip(&#39;\&#39;&#39;&#39; &#39;) + &#39;\&#39;);&#39; 
      print &#39; &#39;.join(lines[1:]) 
    if lines == &#39;&#39;: 
      break 
if __name__ == &#39;__main__&#39;: 
  import sys 
  read_binlog(sys.argv[1],sys.argv[2])
Nach dem Login kopieren

执行脚本:

python restore.py binlog.txt 36 > binlog.sql
Nach dem Login kopieren

命令行中的36 表示 需要还原的表的字段有36个,效果:

INSERT INTO test.me_info 
VALUES ( 
 2123269, 
 &#39;1990:11:12&#39;, 
 NULL, 
 2, 
 &#39;&#39;, 
 0, 
 &#39;&#39;, 
 -1, 
 0, 
 340800, 
 1, 
 0, 
 &#39;&#39;, 
…… 
…… 
 1, 
 NULL 
);
Nach dem Login kopieren

最后还原:

mysql test < binlog.sql
Nach dem Login kopieren


以上就是实现MySQL回滚的Python脚本的编写教程_MySQL的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage