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

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索mysql
, 教程
, 回滚
MySQL教程
mysql 回滚脚本、python mysql回滚、python编写自动化脚本、python脚本编写、python如何编写脚本,以便于您获取更多的相关知识。

时间: 2024-10-03 20:36:12

实现MySQL回滚的Python脚本的编写教程_Mysql的相关文章

mysql 回滚-spring3+mybatis+myql事务不生效

问题描述 spring3+mybatis+myql事务不生效 代码格式为 @Transactional(rollbackFor=java.lang.Exception.class, propagation=Propagation.REQUIRED, readOnly=false) public void excuDevOrAppPagRel(DevPackageRln devPackageRln) throws Exception{ //具体操作,无try-catch操作 } mysql所有表的

急!求助!mysql 回滚无效

问题描述 publicstaticbooleanUpdate(Stringdb,ArrayList<String>sql){Connectioncon=DbConnection.getConnection("db");;Statementpstmt=null;try{pstmt=con.createStatement();con.setAutoCommit(false);for(inti=0;i<sql.size();i++){System.out.println(&

MySQL日志分析软件mysqlsla的安装和使用教程_Mysql

一.下载 mysqlsla [root@localhost tmp]# wget http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz --19:45:45-- http://hackmysql.com/scripts/mysqlsla-2.03.tar.gz Resolving hackmysql.com... 64.13.232.157 Connecting to hackmysql.com|64.13.232.157|:80... connec

MySQL中InnoDB的Memcached插件的使用教程_Mysql

安装    为了让文章更具完整性,我们选择从源代码安装MySQL,需要注意的是早期的版本有内存泄漏,所以推荐安装最新的稳定版,截至本文发稿时为止,最新的稳定版是5.6.13,我们就以此为例来说明,过程很简单,只要激活了WITH_INNODB_MEMCACHED即可: shell> groupadd mysql shell> useradd -r -g mysql mysql shell> tar zxvf mysql-5.6.13.tar.gz shell> cd mysql-5.

MySQL中insert语句的使用与优化教程_Mysql

MySQL 表中使用 INSERT INTO SQL语句来插入数据. 你可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据. 语法 以下为向MySQL数据表插入数据通用的 INSERT INTO SQL语法: INSERT INTO table_name ( field1, field2,...fieldN ) VALUES ( value1, value2,...valueN ); 如果数据是字符型,必须使用单引号或者双引号,如:"value"

MySQL中LIKE子句相关使用的学习教程_Mysql

MySQL LIKE 语法LIKE 运算符用于 WHERE 表达式中,以搜索匹配字段中的指定内容,语法如下: WHERE column LIKE pattern WHERE column NOT LIKE pattern 在 LIKE 前面加上 NOT 运算符时,表示与 LIKE 相反的意思,即选择 column 不包含 pattern 的数据记录. LIKE 通常与通配符 % 一起使用,% 表示通配 pattern 中未出现的内容.而不加通配符 % 的 LIKE 语法,表示精确匹配,其实际效果

windows下安装、卸载mysql服务的方法(mysql 5.6 zip解压版安装教程)_Mysql

MySQL是一个小巧玲珑但功能强大的数据库,目前十分流行.但是官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的.很多人下了zip格式的解压发现没有setup.exe,面对一堆文件一头雾水,不知如何安装.下面笔者将介绍如何解决此情况下安装过程中的各种问题. 比较简单的步骤: 在win2003及win2008 r2以上版本: 将下载下来的mysql解压到指定目录下(如:d:\mysql) 安装服务 在命令行输入 d:\mysql\bin\mysqld -install net sta

mysql 5.7.16 安装配置方法图文教程_Mysql

结合网上的资料,自己亲自的去安装了一次MySQL,安装版本是win7x64 5.7.16. 在安装过程中出现并解决了如下问题: "mysql 服务无法启动 服务没报告任何错误" 1.下载: 地址:http://dev.mysql.com/downloads/mysql/ 2.安装: ZIP Archive版是免安装的.只要解压就行了.不需要安装.我的放在d盘啦. 3.配置: 也就是my.ini文件的由来. 把my-default.ini这个文件复制一下重命名my.ini,然后替换成如下

MySQL中基本的多表连接查询教程_Mysql

一.多表连接类型1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用','  如:         由于其返回的结果为被连接的两个数据表的乘积,因此当有WHERE, ON或USING条件的时候一般不建议使用,因为当数据表项目太多的时候,会非常慢.一般使用LEFT [OUTER] JOIN或者RIGHT [OUTER] JOIN  2.   内连接INNER JOIN 在MySQL中把I SELECT * FROM table1 CROSS J