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 

  • 相关阅读:
    数据库连接字符串
    搭建消息队列
    Linux---江湖
    Bundle压缩JS和CSS
    DDD分层架构之仓储
    UI控件库
    图解Http协议 url长度限制
    JAVA jdbc(数据库连接池)学习笔记(转)
    领域驱动设计(DDD)部分核心概念的个人理解(转)
    怎样的中奖算法能让人信服(转)
  • 原文地址:https://www.cnblogs.com/gomysql/p/3713134.html
Copyright © 2011-2022 走看看