在前面的文章中我们介绍了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. |egrep -i -C  '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=/*!*/;
SET @@session.pseudo_thread_id=/*!*/;
SET @@session.foreign_key_checks=, @@session.sql_auto_is_null=, @@session.unique_checks=, @@session.autocommit=/*!*/;
SET @@session.sql_mode=/*!*/;
SET @@session.auto_increment_increment=, @@session.auto_increment_offset=/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=,@@session.collation_connection=,@@session.collation_server=/*!*/;
SET @@session.lc_time_names=/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
BEGIN
/*!*/;
# at
# at
# :: server id end_log_pos Table_map: `test`.`tb1` mapped to number
#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
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='atlas' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
### SET
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='yayun' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
### UPDATE test.tb1
### WHERE
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='dyy' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
### SET
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='yayun' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
### UPDATE test.tb1
### WHERE
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='nginx' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
### SET
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='yayun' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
### UPDATE test.tb1
### WHERE
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='apache' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
### SET
### @= /* INT meta=0 nullable=1 is_null=0 */
### @='yayun' /* VARSTRING(60) meta=60 nullable=1 is_null=0 */
# at
# :: server id end_log_pos Xid =
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= mysql-bin.
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at
# :: server id end_log_pos Start: binlog v , server v 5.5.25a-log created ::
# 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= --stop-position= mysql-bin. | 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

MySQL模拟Oralce闪回操作的更多相关文章

  1. MySQL的binlog2sql闪回

    从MySQL binlog解析出你要的SQL.根据不同选项,你可以得到原始SQL.回滚SQL.去除主键的INSERT SQL等. 用途=========== * 数据快速回滚(闪回)* 主从切换后新m ...

  2. PLSQL_闪回操作4_Flashback Drop

    2014-06-25 Created By BaoXinjian

  3. PLSQL_闪回操作1_Flashback Query

    2014-07-02 Created By BaoXinjian

  4. oralce闪回

    Oracle闪回操作 1. 记录当前时间或SCN 在数据库变动前记录时间或SCN SQL> select  to_char(sysdate,'YYYY-MM-DD HH24:mi:ss') fr ...

  5. Oracle闪回操作

    Oracle闪回操作 1. 记录当前时间或SCN 在数据库变动前记录时间或SCN SQL> select  to_char(sysdate,'YYYY-MM-DD HH24:mi:ss') fr ...

  6. MYSQL工具之binlog2sql闪回操作

    文档结构: 在生产环境中如果遇到误删,改错数据的情况,利用mysql闪回工具binlog2sql,可以实现数据的快速回滚,从binlog中提取SQL,并能生成回滚SQL语句.Binlog以event作 ...

  7. PLSQL_闪回操作6_Flashback Database

    2014-12-09 Created By BaoXinjian

  8. PLSQL_闪回操作5_Flashback Table

    2014-12-09 Created By BaoXinjian

  9. Oracle的闪回操作

    Oracle10g中引入了闪回技术,但这并不意味着所有的表都能闪回成功,当没有足够的磁盘空间,Oracle将使用回收站中的磁盘空间,而且位图连接索引和引用完整性约束也不受回收站的保护. recycle ...

随机推荐

  1. (转)java 层调用Jni(Ndk) 持久化c c++ 对象

    对于Jni(Ndk) 很多人应该都有印象,Android的ndk接触到的机会相对会比较多,本例子以android平台为例,pc端的话就以简单的windows为例, 编码完用vs 或是 gcc进行编译成 ...

  2. Stanford Corenlp学习笔记——词性标注

    使用Stanford Corenlp对中文进行词性标注 语言为Scala,使用的jar的版本是3.6.0,而且是手动添加jar包,使用sbt添加其他版本的时候出现了各种各样的问题 添加的jar包有5个 ...

  3. shell中的函数 shell中的数组 告警系统需求分析

     

  4. 断网环境下利用pip安装Python离线安装包

    这几天搞Windows离线断网环境下安装Python包,配置环境,各种坑!做个记录,供以后查询吧. # 生产环境 windows 7 # python 2.7.9 # pip 1.5.2 友情提示:当 ...

  5. Tarjan 强连通分量 及 双联通分量(求割点,割边)

    Tarjan 强连通分量 及 双联通分量(求割点,割边) 众所周知,Tarjan的三大算法分别为 (1)         有向图的强联通分量 (2)         无向图的双联通分量(求割点,桥) ...

  6. .NET Core类库项目中如何读取appsettings.json中的配置

    这是一位朋友问我的问题,写篇随笔回答一下.有2种方法,一种叫丑陋的方法 —— IConfiguration ,一种叫优雅的方法 —— IOptions . 1)先看丑陋的方法 比如在 RedisCli ...

  7. vins-mono源码解读

    https://blog.csdn.net/q597967420/article/details/76099409

  8. sql语句 isnull(列名,'')='' /STUFF的意思

    (1) SELECT  SYXH,ZYHM,YEXH,ISNULL(YETZ,'') AS YETZ ,RYKSMC,RYBQMC,HZXM FROM YG_BRSYK 如果列名数据等于NULL,那么 ...

  9. python中OrderedDict的使用

    很多人认为python中的字典是无序的,因为它是按照hash来存储的,但是python中有个模块collections(英文,收集.集合),里面自带了一个子类 OrderedDict,实现了对字典对象 ...

  10. Hive中的order by、sort by、distribute by、cluster by解释及测试

    结论: order by:全局排序,这也是4种排序手段中唯一一个能在终端输出中看出全局排序的方法,只有一个reduce,可能造成renduce任务时间过长,在严格模式下,要求必须具备limit子句. ...