• 【MySQL】使用mysqlbinlog回滚


    参考:http://wubx.net/?s=mysqlbinlog

    mysql官方的mysqlbinlog没有回滚的功能,淘宝大牛对官方代码进行了修改使之能够将binlog中的DML操作变成互逆的语句,比如delete变为insert,update的set和where的互换。不过注意前提是binlog的格式必须是binlog_format=ROW

    另外注意导入回滚数据较多时,需要调整超时时间和最大package的大小:

    binlog_format=ROW

    max_allowed_packet=1024M

    #max_allow_packet大小不够时报错如下:
    ERROR 1153 (08S01) at line 403133: Got a packet bigger than ‘max_allowed_packet’ bytes

    重构代码

    http://mysql.taobao.org/index.php/Patch_source_code#Add_flashback_feature_for_mysqlbinlog

    有三个版本,测试percona5518版本可以使用5.5.18_flashback_all.diff,mysql官方版本只能使用5.5.18_flashback.diff。

    http://mysql.taobao.org/images/5/53/5.5.18_flashback_all.diff

    http://mysql.taobao.org/images/0/0f/5.5.18_flashback.diff

    percona5.5.18版本的下载链接:

    http://www.percona.com/downloads/Percona-Server-5.5/Percona-Server-5.5.18-23.0/source/Percona-Server-5.5.18-rel23.0.tar.gz

    mysql5.5.18

    http://cdn.mysql.com/archives/mysql-5.5/mysql-5.5.18.tar.gz

    cd mysql-5.5.18/
    wget http://mysql.taobao.org/images/0/0f/5.5.18_flashback.diff
    patch -p0 < 5.5.18_flashback.diff
    ## 编译成功无报错即可,无特殊编译参数要求

    编译完成后,开始测试:

    [root@server1 /]# /percona5518/bin/mysqlbinlog --help
    在说明中多了
      -B, --flashback     Flashback data to start_postition or start_datetime.

    然后可以用一个binlog文件做测试

    mysql> select count(1) from t1;
    +----------+
    | count(1) |
    +----------+
    |       16 |
    +----------+
    1 row in set (0.00 sec)
    
    mysql> select * from t1 where id<5;
    +----+------+------+
    | id | a    | b    |
    +----+------+------+
    |  1 | aaaa | bbbb |
    |  2 | aaaa | bbbb |
    |  3 | aaaa | bbbb |
    |  4 | aaaa | bbbb |
    +----+------+------+
    4 rows in set (0.00 sec)
    
    mysql> flush logs;
    Query OK, 0 rows affected (0.11 sec)
    
    mysql> show master status G
    *************************** 1. row ***************************
                File: mysql-bin.000010
            Position: 108
        Binlog_Do_DB: 
    Binlog_Ignore_DB: 
    1 row in set (0.00 sec)
    
    mysql> update t1 set a='XXXX',b='SSSS' where id<5;
    Query OK, 4 rows affected (0.04 sec)
    Rows matched: 4  Changed: 4  Warnings: 0
    
    mysql> flush logs;
    Query OK, 0 rows affected (0.09 sec)
    View Code

    打印出binlog

    [root@server1 bin]# ./mysqlbinlog -uroot -p ../data/mysql-bin.000010 -v -v --base64-output=decode-rows 
    Enter password: 
    /*!40019 SET @@session.max_insert_delayed_threads=0*/;
    /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
    DELIMITER /*!*/;
    # at 4
    #141204 10:51:29 server id 5598  end_log_pos 108        Start: binlog v 4, server v 5.5.18-log created 141204 10:51:29
    # at 108
    #141204 10:52:32 server id 5598  end_log_pos 176        Query   thread_id=13    exec_time=0     error_code=0
    SET TIMESTAMP=1417661552/*!*/;
    SET @@session.pseudo_thread_id=13/*!*/;
    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 176
    # at 223
    #141204 10:52:32 server id 5598  end_log_pos 223        Table_map: `test`.`t1` mapped to number 46
    #141204 10:52:32 server id 5598  end_log_pos 373        Update_rows: table id 46 flags: STMT_END_F
    ### UPDATE test.t1
    ### WHERE
    ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='aaaa' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='bbbb' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### SET
    ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='XXXX' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='SSSS' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### UPDATE test.t1
    ### WHERE
    ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='aaaa' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='bbbb' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### SET
    ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='XXXX' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='SSSS' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### UPDATE test.t1
    ### WHERE
    ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='aaaa' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='bbbb' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### SET
    ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='XXXX' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='SSSS' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### UPDATE test.t1
    ### WHERE
    ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='aaaa' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='bbbb' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### SET
    ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='XXXX' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='SSSS' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    # at 373
    #141204 10:52:32 server id 5598  end_log_pos 400        Xid = 218
    COMMIT/*!*/;
    # at 400
    #141204 10:52:37 server id 5598  end_log_pos 443        Rotate to mysql-bin.000011  pos: 4
    DELIMITER ;
    # End of log file
    ROLLBACK /* added by mysqlbinlog */;
    /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    View Code

    打印出回滚的binlog

    [root@server1 bin]# ./mysqlbinlog -uroot -p ../data/mysql-bin.000010 -v -v --base64-output=decode-rows -B
    Enter password: 
    /*!40019 SET @@session.max_insert_delayed_threads=0*/;
    /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
    DELIMITER /*!*/;
    #141204 10:51:29 server id 5598  end_log_pos 108        Start: binlog v 4, server v 5.5.18-log created 141204 10:51:29
    #141204 10:52:37 server id 5598  end_log_pos 443        Rotate to mysql-bin.000011  pos: 4
    #141204 10:52:32 server id 5598  end_log_pos 400        Xid = 218
    COMMIT/*!*/;
    #141204 10:52:32 server id 5598  end_log_pos 223        Table_map: `test`.`t1` mapped to number 46
    #141204 10:52:32 server id 5598  end_log_pos 373        Update_rows: table id 46 flags: STMT_END_F
    ### UPDATE test.t1
    ### WHERE
    ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='XXXX' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='SSSS' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### SET
    ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='aaaa' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='bbbb' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### UPDATE test.t1
    ### WHERE
    ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='XXXX' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='SSSS' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### SET
    ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='aaaa' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='bbbb' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### UPDATE test.t1
    ### WHERE
    ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='XXXX' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='SSSS' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### SET
    ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='aaaa' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='bbbb' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### UPDATE test.t1
    ### WHERE
    ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='XXXX' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='SSSS' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ### SET
    ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    ###   @2='aaaa' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    ###   @3='bbbb' /* VARSTRING(15) meta=15 nullable=1 is_null=0 */
    DELIMITER ;
    # End of log file
    ROLLBACK /* added by mysqlbinlog */;
    /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    View Code

    delete语句的回滚是把delete换成了insert

    在导入的时候遇到了问题,导入一直不成功。

    [root@server1 bin]# ./mysqlbinlog ../data/mysql-bin.000010 -v -v --base64-output=decode-rows  -B |  ./mysql -uroot -p -S ../tmp/mysql.sock  test
    没有效果!

    后来发现是参数的问题,再试成功了,如果使用mysql官方版本好像除了-B 参数不用带其他参数,如果测试有问题可以增减参数试试。

    [root@server1 bin]# ./mysqlbinlog ../data/mysql-bin.000010 -v-v -B |  ./mysql -uroot -p -S ../tmp/mysql.sock  test

    另外注意几个比较实用的参数

      --start-datetime=name 
                          Start reading the binlog at first event having a datetime
                          equal or posterior to the argument; the argument must be
                          a date and time in the local time zone, in any format
                          accepted by the MySQL server for DATETIME and TIMESTAMP
                          types, for example: 2004-12-25 11:25:56 (you should
                          probably use quotes for your shell to set it properly).
      -j, --start-position=# 
                          Start reading the binlog at position N. Applies to the
                          first binlog passed on the command line.
      --stop-datetime=name 
                          Stop reading the binlog at first event having a datetime
                          equal or posterior to the argument; the argument must be
                          a date and time in the local time zone, in any format
                          accepted by the MySQL server for DATETIME and TIMESTAMP
                          types, for example: 2004-12-25 11:25:56 (you should
                          probably use quotes for your shell to set it properly).
      --stop-position=#   Stop reading the binlog at position N. Applies to the
                          last binlog passed on the command line.
    
      -d, --database=name List entries for just this database (local log only).
    
      -f, --force-read    Force reading unknown binlog events.

    恢复一个事务,找到开始和结束的pos位置

    [root@server1 bin]# ./mysqlbinlog -v -v ../mysql-bin.000012  --start-position=1680 --stop-position=1971 -B |  ./mysql -uroot -p -S ../tmp/mysql.sock  test

    如何能回滚一个binlog中一个表的数据而不影响其他表?如果是一个事务可以使用“--start-position=”和“--stop-position=”,如果不是一个连续的事务呢?

    参考:http://hcymysql.blog.51cto.com/5223301/1553080

    不过我在5.5的版本中测试不能给库级和表级授权super

  • 相关阅读:
    nyoj 139 我排第几个--康拓展开
    树形dp--hdu 3534 Tree
    hdu 2196 Computer 树形dp模板题
    poj 2342 Anniversary party 简单树形dp
    hdu 4738 Caocao's Bridges 图--桥的判断模板
    poj 1144 Network 图的割顶判断模板
    poj 3159 Candies 差分约束
    poj 3169 Layout 差分约束模板题
    codeforces C. Triangle
    java中过滤器、监听器、拦截器的区别
  • 原文地址:https://www.cnblogs.com/jiangxu67/p/4140882.html
Copyright © 2020-2023  润新知