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

操作数据库时候难免会因为“大意”而误操作,需要快速恢复的话通过备份来恢复是不太可能的,因为需要还原和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

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

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 ''.join(lines).find('@') <> -1 and lines[3].split('=',1)[0] <> num:     #num为列数,要是小于最大的列数,后面均加,
        lines[3] = lines[3].split('=',1)[-1].strip()
        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 restore.py binlog.txt 36 > binlog.sql

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

INSERT INTO test.me_info
VALUES (
 2123269,
 '1990:11:12',
 NULL,
 2,
 '',
 0,
 '',
 -1,
 0,
 340800,
 1,
 0,
 '',
……
……
 1,
 NULL
);

最后还原:

mysql test < binlog.sql
(0)

相关推荐

  • Python备份Mysql脚本

    复制代码 代码如下: #!/usr/bin/python import os  import time  import ftplib  import traceback #config vars  systempathchr="/" #路径分割符,*nix用"/" win32用"\\" dbuser="root" #数据库用户名  dbpwd="dbpwd" #数据库密码  dbnamelist=[&quo

  • Python操作Mysql实例代码教程在线版(查询手册)

    实例1.取得MYSQL的版本在windows环境下安装mysql模块用于python开发 MySQL-python Windows下EXE安装文件下载 复制代码 代码如下: # -*- coding: UTF-8 -*- #安装MYSQL DB for pythonimport MySQLdb as mdb con = None try:    #连接mysql的方法:connect('ip','user','password','dbname')    con = mdb.connect('l

  • python Django连接MySQL数据库做增删改查

    1.下载安装MySQLdb类库http://www.djangoproject.com/r/python-mysql/2.修改settings.py 配置数据属性 复制代码 代码如下: DATABASES = {    'default': {        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.        'NAME': 'djang

  • Python下的Mysql模块MySQLdb安装详解

    默认情况下,MySQLdb包是没有安装的,不信? 看到类似下面的代码你就信了. 复制代码 代码如下: -bash-3.2# /usr/local/python2.7.3/bin/python get_cnblogs_news.py Traceback (most recent call last):  File "get_cnblogs_news.py", line 9, in <module>    import MySQLdbImportError: No module

  • MySQL-Python安装问题小记

    安装完mysql-python后import加载模块提示以下错误, 复制代码 代码如下: ImportError: libmysqlclient_r.so.16: cannot open shared object file: No such file or directory 于是google之,总结一下解决方法: (1)在mysql-ython的安装目录下找到site.cfg,将 #mysql_config = XXXXXXXXXXXXXXXX 注释符号去掉,并填上mysql_config的

  • Python连接MySQL并使用fetchall()方法过滤特殊字符

    来一个简单的例子,看Python如何操作数据库,相比Java的JDBC来说,确实非常简单,省去了很多复杂的重复工作,只关心数据的获取与操作. 准备工作 需要有相应的环境和模块: Ubuntu 14.04 64bit Python 2.7.6 MySQLdb 注意:Ubuntu 自带安装了Python,但是要使用Python连接数据库,还需要安装MySQLdb模块,安装方法也很简单: sudo apt-get install MySQLdb 然后进入Python环境,import这个包,如果没有报

  • python中MySQLdb模块用法实例

    本文实例讲述了python中MySQLdb模块用法.分享给大家供大家参考.具体用法分析如下: MySQLdb其实有点像php或asp中连接数据库的一个模式了,只是MySQLdb是针对mysql连接了接口,我们可以在python中连接MySQLdb来实现数据的各种操作. python连接mysql的方案有oursql.PyMySQL. myconnpy.MySQL Connector 等,不过本篇要说的确是另外一个类库MySQLdb,MySQLdb 是用于Python链接Mysql数据库的接口,它

  • python访问mysql数据库的实现方法(2则示例)

    本文实例讲述了python访问mysql数据库的实现方法.分享给大家供大家参考,具体如下: 首先安装与Python版本匹配的MySQLdb 示例一 import MySQLdb conn=MySQLdb.connect(user='root',passwd='123',db='example') cur=conn.cursor() cur.execute("select id,lastname,firstname, date_format(dob,'%Y-%m-%d %H-%i-%s'),pho

  • python mysqldb连接数据库

    没办法就下了一个2.6,如果用2.4就太低了,又折腾了,半天找到了MySQL-python-1.2.2.win32-py2.6.exe 这个安装文件,安装完成,执行 import MySQLdb 出现问题提示: File "C:\Python26\lib\site-packages\MySQLdb\__init__.py", line 19, in <module> ImportError: DLL load failed: 找不到指定的模块. 经过无数的查找,发现官方的说

  • python连接mysql数据库示例(做增删改操作)

    一.相关代码数据库配置类 MysqlDBConn.py 复制代码 代码如下: #encoding=utf-8'''Created on 2012-11-12 Mysql Conn连接类''' import MySQLdb class DBConn: conn = None #建立和数据库系统的连接    def connect(self):        self.conn = MySQLdb.connect(host="localhost",port=3306,user="

随机推荐