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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM