MySQL閃回工具--MyFlash


(一)MyFlash介紹

MyFlash是美團開發的一個回滾DML操作的工具,該工具是開源的,github地址為:https://github.com/Meituan-Dianping/MyFlash。通過該工具,可以實現MySQL數據庫的閃回。

 

(二)安裝MyFlash

下載源碼:

git clone https://github.com/Meituan-Dianping/MyFlash.git

安裝依賴包:

yum install -y gcc pkg-config glib2 libgnomeui-devel

編譯:

[root@masterdb MyFlash]# gcc -w  `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c  -o binary/flashback

 

(三)使用MyFlash

MyFlash語法為:

[root@masterdb binary]# pwd
/root/MyFlash/binary
[root@masterdb binary]# ./flashback --help Usage: flashback [OPTION?] Help Options: -h, --help Show help options Application Options: --databaseNames databaseName to apply. if multiple, seperate by comma(,) --tableNames tableName to apply. if multiple, seperate by comma(,) --start-position start position --stop-position stop position --start-datetime start time (format %Y-%m-%d %H:%M:%S) --stop-datetime stop time (format %Y-%m-%d %H:%M:%S) --sqlTypes sql type to filter . support INSERT, UPDATE ,DELETE. if multiple, seperate by comma(,) --maxSplitSize max file size after split, the uint is M --binlogFileNames binlog files to process. if multiple, seperate by comma(,) --outBinlogFileNameBase output binlog file name base --logLevel log level, available option is debug,warning,error --include-gtids gtids to process --exclude-gtids gtids to skip

語法解析:

  • --databaseNames : 需要閃回的數據庫名稱,如果有多個數據庫,用逗號”,”隔開。
  • --tableNames : 要閃回的表名稱,如果有多個表,用逗號”,”隔開。
  • --start-position :閃回的起始位置,如不指定,從文件開始處回滾。
  • --stop-position : 閃回的終止位置,如不指定,回滾到文件結尾。
  • --start-datetime : 閃回的開始時間。
  • --stop-datetime : 閃回的終止時間。
  • --sqlTypes : 指定需要回滾的sql類型,支持INSERT、UPDATE、DELETE,多個類型使用逗號”,”分開。
  • --maxSplitSize : 對文件進行固定尺寸的切割,以防止單次應用binlog尺寸較大,對線上造成壓力。
  • --binlogFileNames : 指定需要回滾的binlog文件,美團文檔說目前只支持單個binlog文件,經測試已經支持多個binlog文件同時閃回。
  • --outBinlogFileNameBase :指定輸出的binlog文件前綴,如不指定,則默認為binlog_output_base.flashback。
  • logLevel : 僅供開發者使用,默認級別為error級別。在生產環境中不要修改這個級別,否則輸出過多。
  • include-gtids : 指定需要回滾的gtid,支持gtid的單個和范圍兩種形式。
  • exclude-gtids : 指定不需要回滾的gtid,用法同include-gtids。

 

(四)MyFlash測試

(4.1)測試MyFlash閃回功能

STEP1:構造測試數據

[root@masterdb binary]# mysql -uroot -p123456 lijiamandb

mysql> select * from test01; +----+--------+------------+ | id | name | birthday | +----+--------+------------+ | 1 | 小明 | 1993-01-02 | | 2 | 小華 | 1994-08-15 | | 3 | 小麗 | 1995-07-12 | +----+--------+------------+ 3 rows in set (0.00 sec)

 

STEP2:執行插入、更新、刪除操作

mysql> insert into test01 values(4,'小紅','2000-01-01');
Query OK, 1 row affected (0.01 sec) mysql> delete from test01 where id = 1; Query OK, 1 row affected (0.03 sec) mysql> update test01 set birthday = '1994-09-15'; Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql> select * from test01; +----+--------+------------+ | id | name | birthday | +----+--------+------------+ | 2 | 小華 | 1994-09-15 | | 3 | 小麗 | 1994-09-15 | | 4 | 小紅 | 1994-09-15 | +----+--------+------------+ 3 rows in set (0.00 sec)

 

STEP3:確認上面的DML操作二進制日志

mysql> show master status;
 +-------------------+----------+--------------+------------------+-------------------+
 | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
 +-------------------+----------+--------------+------------------+-------------------+
 | master-bin.000001 |     1079 |              |                  |                   |
 +-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


STEP4:發現誤刪除(delete)數據,要求恢復(需要2步)

執行閃回操作,將閃回結果存放到binlog_output_base.flashback中

[root@masterdb binary]# ./flashback --databaseNames=lijiamandb --tableNames=test01 --sqlTypes='DELETE' --binlogFileNames=/mysql/binlog/master-bin.000001
 [root@masterdb binary]# ls -lrt total 7320 -rwxr-xr-x 1 root root 7463125 Apr 24 14:03 mysqlbinlog20160408 -rwxr-xr-x 1 root root 54272 Apr 24 14:14 flashback -rw-r--r-- 1 root root 263 Apr 24 14:38 binlog_output_base.flashback

應用閃回的日志:

[root@masterdb binary]# mysqlbinlog binlog_output_base.flashback | mysql -uroot -p123456

 

STEP5:確認結果,已經將“DELETE”刪除的數據找了回來

mysql> select * from test01;
+----+--------+------------+
| id | name   | birthday   |
+----+--------+------------+
|  1 | 小明   | 1993-01-02 |
 |  2 | 小華   | 1994-09-15 |
 |  3 | 小麗   | 1994-09-15 |
 |  4 | 小紅   | 1994-09-15 |
+----+--------+------------+
4 rows in set (0.00 sec)

 

 

(4.2)測試MyFlash同時應用多個binlog日志閃回

STEP1:確認初始數據

[root@masterdb binary]# mysql -uroot -p123456 lijiamandb

mysql> select * from test01; +----+--------+------------+ | id | name | birthday | +----+--------+------------+ | 1 | 小明 | 1993-01-02 | | 2 | 小華 | 1994-09-15 | | 3 | 小麗 | 1994-09-15 | | 4 | 小紅 | 1994-09-15 | +----+--------+------------+ 4 rows in set (0.00 sec)

 

STEP2:修改數據,並切換日志

mysql> update test01 set birthday = '1998-01-12' where id = 4;
 Query OK, 1 row affected (0.02 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> show master status; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000001 | 1651 | | | | +-------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> flush logs; Query OK, 0 rows affected (0.01 sec) mysql> show master status; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000002 | 154 | | | | +-------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> update test01 set name = 'a' where id = 2; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from test01; +----+--------+------------+ | id | name | birthday | +----+--------+------------+ | 1 | 小明 | 1993-01-02 | | 2 | a | 1994-09-15 | | 3 | 小麗 | 1994-09-15 | | 4 | 小紅 | 1998-01-12 | +----+--------+------------+ 4 rows in set (0.00 sec) mysql> flush logs -> ; Query OK, 0 rows affected (0.00 sec) mysql> show master status; +-------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------+----------+--------------+------------------+-------------------+ | master-bin.000003 | 154 | | | | +-------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> update test01 set birthday='2000-12-12' where id = 3; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from test01; +----+--------+------------+ | id | name | birthday | +----+--------+------------+ | 1 | 小明 | 1993-01-02 | | 2 | a | 1994-09-15 | | 3 | 小麗 | 2000-12-12 | | 4 | 小紅 | 1998-01-12 | +----+--------+------------+ 4 rows in set (0.00 sec) mysql> exit Bye

 

STEP3:執行閃回操作

[root@masterdb binary]# ./flashback --databaseNames=lijiamandb --tableNames=test01 --sqlTypes='UPDATE' --outBinlogFileNameBase=test01_update.flashback --binlogFileNames=/mysql/binlog/master-bin.000001,/mysql/binlog/master-bin.000002,/mysql/binlog/master-bin.000003

[root@masterdb binary]# ls -lrt
total 7332
-rwxr-xr-x 1 root root 7463125 Apr 24 14:03 mysqlbinlog20160408 -rwxr-xr-x 1 root root 54272 Apr 24 14:14 flashback -rw-r--r-- 1 root root 263 Apr 24 14:38 binlog_output_base.flashback -rw-r--r-- 1 root root 495 Apr 24 14:58 test01_update.flashback.flashback.000002 -rw-r--r-- 1 root root 274 Apr 24 14:58 test01_update.flashback.flashback.000001 -rw-r--r-- 1 root root 279 Apr 24 14:58 test01_update.flashback.flashback [root@masterdb binary]# mysqlbinlog test01_update.flashback.flashback test01_update.flashback.flashback.000001 test01_update.flashback.flashback.000002| mysql -uroot -p123456 mysql: [Warning] Using a password on the command line interface can be insecure.


STEP4:確認數據,發現回滾到了最老的數據,不符合要求

[root@masterdb binary]# mysql -uroot -p123456 lijiamandb
 mysql> select * from test01; +----+--------+------------+ | id | name | birthday | +----+--------+------------+ | 1 | 小明 | 1993-01-02 | | 2 | 小華 | 1994-08-15 | | 3 | 小麗 | 1995-07-12 | | 4 | 小紅 | 2000-01-01 | +----+--------+------------+ 4 rows in set (0.00 sec)

 思路整理:

我們對數據進行多次更新,但是在使用binlog進行閃回的時候,沒有指定開始、結束位置,因此對所有日志都進行了閃回,從而將數據閃回到了最初的數據,不符合我們的要求。如果我們指定合理的開始結束位置,還是可以將數據閃回到任意時刻的。

image

 

 (五)總結

1.如果binlog日志存在,那么可以使用MyFlash將數據庫閃回到任意時刻。

2.可以對整個實例進行閃回、也可以對某個database,或者是某張表進行閃回,還可以指定某種DML操作進行閃回。

3.MyFlash閃回也有一定的局限性。在閃回時,指定出閃回的開始和結束時間/位置依然是最為重要的,但使用flashback是無法查看二進制日志的,意味着在使用MyFlash時,要么預估開始結束時間,進行不精確的閃回,要么使用mysqlbinlog或binlog2sql來分析日志,得到精確的開始結束時間再閃回。

4.從測試來看,binlog2sql似乎比MyFlash更好用,但是為什么在已經有binlog2sql的基礎上,還要開發MyFlash呢?最主要還是MyFlash性能非常好,閃回速度非常快,美團測試報告中,使用各個工具對約100萬條數據進行閃回的測試如下(原文點這):

image

 

【完】

 

 

 

 

相關文檔集合:

1.MySQL日志--二進制日志(binlog)                   
2.使用mysqlbinlog查看二進制日志                   
3.MySQL使用mysqldump+binlog完整恢復被刪除的數據庫 
4.使用binlog2sql工具來恢復數據庫                  
5.MySQL閃回工具—MyFlash                           


免責聲明!

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



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