zoukankan      html  css  js  c++  java
  • MySQL模拟Oralce闪回操作

    在前面的文章中我们介绍了MySQL误操作后数据恢复(update,delete忘加where条件),大概操作是通过sed命令把binlog中相关SQL误操作给逆向回来,然后导入SQL文件来恢复错误操作,sed相关命令也比较复杂。如果没有正则基础的同学肯定搞不清楚在干嘛。今天无意中发现淘宝的大神(翻译高性能mysql第三版的作者之一)开发了一个补丁,该补丁能够模拟Oracle的闪回操作,这样以来我们的MySQL也可以实现闪回咯。真是给力。注意:同样binlog格式需要是ROW

    项目主页:http://mysql.taobao.org/index.php/Patch_source_code#Add_flashback_feature_for_mysqlbinlog

    测试过程 

    1.给mysql打补丁,该补丁是针对mysql 5.5.18的版本,我测试的mysql 5.5.25版本也可以。(也可以使用我编译好了的,64位平台下的,在文中最后会有下载地址)

    wget http://mysql.taobao.org/images/0/0f/5.5.18_flashback.diff
    cd /usr/local/src/mysql-5.5.25a/
    patch -p0 < /root/5.5.18_flashback.diff
    cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
    make && make install

    2.检查补丁是否应用成功,如果mysqlbinlog命令多了-B选项,那么就ok了。

    [root@yayun-mysql-server ~]# mysqlbinlog --help | grep '-B'
      -B, --flashback     Flashback data to start_postition or start_datetime.
    [root@yayun-mysql-server ~]# 

    3.模拟误操作(update忘记加where条件)

    (root@yayun-mysql-server) [test]> select * from tb1;         
    +------+--------+
    | id   | name   |
    +------+--------+
    |    1 | yayun  |
    |    2 | atlas  |
    |    3 | dyy    |
    |    4 | nginx  |
    |    5 | apache |
    +------+--------+
    5 rows in set (0.00 sec)
    
    (root@yayun-mysql-server) [test]> update tb1 set name='yayun';
    Query OK, 4 rows affected (0.03 sec)
    Rows matched: 5  Changed: 4  Warnings: 0
    
    (root@yayun-mysql-server) [test]> select * from tb1;          
    +------+-------+
    | id   | name  |
    +------+-------+
    |    1 | yayun |
    |    2 | yayun |
    |    3 | yayun |
    |    4 | yayun |
    |    5 | yayun |
    +------+-------+
    5 rows in set (0.00 sec)
    
    (root@yayun-mysql-server) [test]> 

    4.开始恢复

    (1)首先需要找出错误的操作语句以及position点。

    (root@yayun-mysql-server) [test]> show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000023 |      364 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    
    (root@yayun-mysql-server) [test]> 

    可见现在正在使用的是mysql-bin.000023这个binlog

    [root@yayun-mysql-server mysql]# mysqlbinlog -vv mysql-bin.000023 |egrep -i -C 20 'update|tb1'
    # Warning: this binlog is either in use or was not closed properly.
    BINLOG '
    RgZoUw8BAAAAZwAAAGsAAAABAAQANS41LjI1YS1sb2cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA==
    '/*!*/;
    # at 107
    #140506  5:45:21 server id 1  end_log_pos 175   Query   thread_id=3     exec_time=0     error_code=0
    SET TIMESTAMP=1399326321/*!*/;
    SET @@session.pseudo_thread_id=3/*!*/;
    SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    SET @@session.sql_mode=0/*!*/;
    SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    /*!C utf8 *//*!*/;
    SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    SET @@session.lc_time_names=0/*!*/;
    SET @@session.collation_database=DEFAULT/*!*/;
    BEGIN
    /*!*/;
    # at 175
    # at 220
    #140506  5:45:21 server id 1  end_log_pos 220   Table_map: `test`.`tb1` mapped to number 35
    #140506  5:45:21 server id 1  end_log_pos 337   Update_rows: table id 35 flags: STMT_END_F
    
    BINLOG '
    cQZoUxMBAAAALQAAANwAAAAAACMAAAAAAAEABHRlc3QAA3RiMQACAw8CPAAD
    cQZoUxgBAAAAdQAAAFEBAAAAACMAAAAAAAEAAv///AIAAAAFYXRsYXP8AgAAAAV5YXl1bvwDAAAA
    A2R5efwDAAAABXlheXVu/AQAAAAFbmdpbnj8BAAAAAV5YXl1bvwFAAAABmFwYWNoZfwFAAAABXlh
    eXVu
    '/*!*/;
    ### UPDATE test.tb1
    ### WHERE
    ###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
    ###   @2='atlas' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
    ### SET
    ###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
    ###   @2='yayun' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
    ### UPDATE test.tb1
    ### WHERE
    ###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
    ###   @2='dyy' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
    ### SET
    ###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
    ###   @2='yayun' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
    ### UPDATE test.tb1
    ### WHERE
    ###   @1=4 /* INT meta=0 nullable=1 is_null=0 */
    ###   @2='nginx' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
    ### SET
    ###   @1=4 /* INT meta=0 nullable=1 is_null=0 */
    ###   @2='yayun' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
    ### UPDATE test.tb1
    ### WHERE
    ###   @1=5 /* INT meta=0 nullable=1 is_null=0 */
    ###   @2='apache' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
    ### SET
    ###   @1=5 /* INT meta=0 nullable=1 is_null=0 */
    ###   @2='yayun' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
    # at 337
    #140506  5:45:21 server id 1  end_log_pos 364   Xid = 40
    COMMIT/*!*/;
    DELIMITER ;
    # End of log file
    ROLLBACK /* added by mysqlbinlog */;
    /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

    开始的起点以107为准,因为107下面紧跟着BEGIN,结束的点以end_log_pos 337下一个点为准.

    [root@yayun-mysql-server mysql]# mysqlbinlog -vv --start-position=337 mysql-bin.000023
    /*!40019 SET @@session.max_insert_delayed_threads=0*/;
    /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
    DELIMITER /*!*/;
    # at 4
    #140506  5:44:38 server id 1  end_log_pos 107   Start: binlog v 4, server v 5.5.25a-log created 140506  5:44:38
    # Warning: this binlog is either in use or was not closed properly.
    BINLOG '
    RgZoUw8BAAAAZwAAAGsAAAABAAQANS41LjI1YS1sb2cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAVAAEGggAAAAICAgCAA==
    '/*!*/;
    # at 337
    #140506  5:45:21 server id 1  end_log_pos 364   Xid = 40
    COMMIT/*!*/;
    DELIMITER ;
    # End of log file
    ROLLBACK /* added by mysqlbinlog */;
    /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    [root@yayun-mysql-server mysql]# 

    上面蓝色字体显示的很清楚了,那么结束的点就是364,因为下面紧跟着COMMIT。现在我们已经找到了日志开始起点为107,结束点为364,下面开始恢复。

    [root@yayun-mysql-server mysql]# mysqlbinlog -B -vv --start-position=107 --stop-position=364 mysql-bin.000023 | mysql
    [root@yayun-mysql-server mysql]# 

    检查是否恢复成功:

    (root@yayun-mysql-server) [test]> select * from tb1;
    +------+--------+
    | id   | name   |
    +------+--------+
    |    1 | yayun  |
    |    2 | atlas  |
    |    3 | dyy    |
    |    4 | nginx  |
    |    5 | apache |
    +------+--------+
    5 rows in set (0.00 sec)
    
    (root@yayun-mysql-server) [test]> 

    可见数据已经成功恢复。其实原理和我们前面通过sed操作binlog进行恢复是一样的。只是这个更简单。对于delete忘记添加where条件,恢复方法是一样的。这里不再重复。

    总结:

    binlog格式非常重要,无论是数据恢复还是主从复制,ROW格式都非常的给力。当然也有缺点,复制会占用过多带宽,消耗大量磁盘空间。

    已经应用补丁的mysqlbinlog下载地址(64位平台,直接替换原来的即可)

    http://pan.baidu.com/s/1o6jXt14 

  • 相关阅读:
    读书笔记之理想设计的特征
    一些javascript 变量声明的 疑惑
    LINQ 使用方法
    Google MySQL tool releases
    读书笔记之设计的层次
    EF之数据库连接问题The specified named connection is either not found in the configuration, not intended to be used with the Ent
    转载 什么是闭包
    javascript面向对象起步
    Tips
    数据结构在游戏中的应用
  • 原文地址:https://www.cnblogs.com/gomysql/p/3713134.html
Copyright © 2011-2022 走看看