首页 > 数据库 > mysql教程 > 实现MySQL回滚的Python脚本的编写教程_MySQL

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

PHP中文网
发布: 2016-05-27 13:45:48
原创
1563 人浏览过

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

条件:开启Binlog,Format为Row。

步骤:

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

1

2

3

4

5

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

登录后复制

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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

……………………

……………………

……………………

登录后复制

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点清楚之后,可以写一个脚本(水平有限,在提升中,写的不好看):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

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

登录后复制

执行脚本:

1

python restore.py binlog.txt 36 > binlog.sql

登录后复制

命令行中的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 
);
登录后复制

最后还原:

1

mysql test < binlog.sql

登录后复制


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


相关标签:
来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板