开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1719|回复: 2
打印 上一主题 下一主题
收起左侧

[Mysql] MySQL遭遇DELETE误操作的回滚

[复制链接]

结帖率:61% (35/57)
跳转到指定楼层
楼主
发表于 2013-1-25 21:43:40 | 只看该作者 回帖奖励 |正序浏览 |阅读模式   海南省海口市
方法:
条件:开启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':           #该部分替换DeleteInsert
  •                 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
总结:
下次整理Row和STATEMENT的优劣。小松鼠

结帖率:37% (7/19)
板凳
发表于 2013-2-2 09:03:54 | 只看该作者   北京市北京市
我看眼花了
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)

签到天数: 1 天

沙发
发表于 2013-1-25 22:36:30 | 只看该作者   福建省三明市
我晕了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:[email protected]
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表