我之前写过一篇《update忘加where条件误操作恢复过程演示》,是通过分析binlog,把binlog用shell转换成误操作之前的sql语句,再导入到数据库中恢复,这个操作过
我之前写过一篇《update忘加where条件误操作恢复过程演示》,是通过分析binlog,把binlog用shell转换成误操作之前的sql语句,再导入到数据库中恢复,这个操作过程很复杂。
如今,淘宝开发了一个闪回工具,,项目主页:,原理同上,但操作过程方便了很多。
下面我来演示一下:
1、下载mysql5.5.18源代码
2、下载闪回补丁
# wget
3、打补丁
# cd mysql-5.5.18
# patch -p0
4、编译mysql并安装
# cmake -dcmake_install_prefix=/usr/local/mysql_flashback
# make;make install
操作:
mysql> select * from t1;+----+| id |+----+| 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 |+----+8 rows in set (0.00 sec)mysql> update t1 set id=id+10;query ok, 8 rows affected (0.00 sec)rows matched: 8 changed: 8 warnings: 0
首先把那条误操作的语句找出来,并且得到position点。
root@m1:/var/log/mysql# mysqlbinlog -vv mysql-bin.000001 |egrep -i -c 20 'update|t1' |morerollback/*!*/;binlog 'tpugug8baaaazwaaagsaaaabaaqans41ljmxltard2hlzxp5ms1sb2caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac2m4zsezgnaagaegaebaqeegaavaaegggaaaaicagcaa=='/*!*/;# at 107#131116 6:10:01 server id 1 end_log_pos 175 query thread_id=44 exec_time=0error_code=0set timestamp=1384553401/*!*/;set @@session.pseudo_thread_id=44/*!*/;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=8/*!*/;set @@session.lc_time_names=0/*!*/;set @@session.collation_database=default/*!*/;begin/*!*/;# at 175# at 216#131116 6:10:01 server id 1 end_log_pos 216 table_map: `test`.`t1` mapped to number 42#131116 6:10:01 server id 1 end_log_pos 326 update_rows: table id 42 flags: stmt_end_fbinlog 'uzuguhmbaaaakqaaangaaaaaacoaaaaaaaeabhrlc3qaanqxaaedaaa=uzuguhgbaaaabgaaaeybaaaaacoaaaaaaaeaaf///geaaad+cwaaap4caaaa/gwaaad+awaaap4naaaa/gqaaad+dgaaap4faaaa/g8aaad+bgaaap4qaaaa/gcaaad+eqaaap4iaaaa/hiaaaa='/*!*/;### update `test`.`t1`### where### @1=1 /* int meta=0 nullable=0 is_null=0 */### set### @1=11 /* int meta=0 nullable=0 is_null=0 */### update `test`.`t1`### where### @1=2 /* int meta=0 nullable=0 is_null=0 */### set### @1=12 /* int meta=0 nullable=0 is_null=0 */### update `test`.`t1`### where### @1=3 /* int meta=0 nullable=0 is_null=0 */### set### @1=13 /* int meta=0 nullable=0 is_null=0 */### update `test`.`t1`### where### @1=4 /* int meta=0 nullable=0 is_null=0 */### set### @1=14 /* int meta=0 nullable=0 is_null=0 */--more--
开始的起点以107为准,因为107下面紧跟着begin,结束的点以end_log_pos 326下一个点为准,
root@m1:/var/log/mysql# mysqlbinlog -vv --start-position=326 mysql-bin.000001 |more/*!50530 set @@session.pseudo_slave_mode=1*/;/*!40019 set @@session.max_insert_delayed_threads=0*/;/*!50003 set @old_completion_type=@@completion_type,completion_type=0*/;delimiter /*!*/;# at 4#131116 6:09:58 server id 1 end_log_pos 107 start: binlog v 4, server v 5.5.31-0+wheezy1-log created 131116 6:09:58 at startup# warning: this binlog is either in use or was not closed properly.rollback/*!*/;binlog 'tpugug8baaaazwaaagsaaaabaaqans41ljmxltard2hlzxp5ms1sb2caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac2m4zsezgnaagaegaebaqeegaavaaegggaaaaicagcaa=='/*!*/;# at 326#131116 6:10:01 server id 1 end_log_pos 395 query thread_id=44 exec_time=0error_code=0set timestamp=1384553401/*!*/;set @@session.pseudo_thread_id=44/*!*/;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=8/*!*/;set @@session.lc_time_names=0/*!*/;set @@session.collation_database=default/*!*/;commit/*!*/;delimiter ;--more--这里
# at 326
#131116 6:10:01 server id 1 end_log_pos 395
那么结束的点就是395,因为下面紧跟着commit
现在我们已经找到了开始起点为107,结束点为395,下面开始恢复。
# mysqlflashback -b -vv --start-position=107 --stop-position=395 mysql-bin.000001 | mysql
mysql> select * from t1; +----+| id |+----+| 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 |+----+8 rows in set (0.00 sec)
大功告成。
同样的方法,delete操作也一样
mysql> select * from t1;+----+| id |+----+| 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 |+----+8 rows in set (0.00 sec)mysql> delete from t1;query ok, 8 rows affected (0.08 sec)mysql> select * from t1;empty set (0.00 sec)
我们可以看到binlog里,把刚刚delete的行,变成了insert
注:这里一定要设置binlog格式row,否则不能恢复。
mysqlflashback我已经编译完,如果嫌麻烦自己不想编译,请在附件里下载我编译好的,64位版本。
本文出自 “贺春旸的技术专栏” 博客,请务必保留此出处