開源插件MySQL-Plugin-Recycle-Bin

MySQL-Plugin-Recycle-Bin簡介

一、簡介

recycle_bin是一款MySQL插件,可以在不修改任何MySQL代碼的情況下,自動備份MySQL中被Drop的表,在出現人爲誤操作刪表時,可以快速的進行恢復,
實現思路借鑑了Oracle flashback的功能,但是從功能完整性上來講,還有較大的差距,目前仍在完善中。
項目地址

https://github.com/sunashe/MySQL-Plugin-Recycle-Bin

recycle_bin並不直接作用於master,而是工作在主從環境中的從機上,當通過程序或者人爲在master上進行drop table操作時,slave會攔截drop操作,
先進行數據備份,再進行刪除操作。當備份文件超過保存時間後,recycle_bin會自動清除這些備份數據。

歡迎加入MySQL內核交流羣

image_1d4f588vm3i83go18ht1bk3gaq9.png-106.5kB

長久以來,MySQL DBA通過一系列的方法限制非超級用戶的Drop權限來避免數據表的誤刪除操作。但是權限收斂並不意味着不需要去進行Drop操作,一旦實施Drop操作,無論是手動還是通過程序自動化進行,就都有可能出現誤操作。更不要說一些沒有專人維護的數據庫實例,RD直接操作數據庫更容易引起誤刪的問題。

即便我們已經有了非常完善的備份策略,可以通過全量+增量的方式恢復刪除的數據,但是時間成本太高;還有系統級別的數據恢復方案等等,也不能完全保證數據可以恢復到完全一致的狀態,可能出現一次核心業務的表誤刪除操作,全年RTO就不達標。

然之後我們又想通過複製延遲來解決這個問題,在master上執行了drop操作之後,slave在設定時間內不會應用日誌,所以可以通過slave找到相對應的數據。但這個方案會影響正常數據庫切換邏輯,監控處理邏輯等等。總之,對我們現有的一套運維方案,高可用架構的侵入性太強。

而Recycle_Bin這個插件就是爲了解決這些痛點而生的,當master出現錯誤的drop操作時,slave不會原本按照master的刪除方式進行刪除,將被刪除的表放到用戶可執行的備份數據庫中。
此時的數據恢復方案可以有一下兩種選擇

  • 從slave中將數據導出,導入到master中
  • 做主從切換,新主上直接rename即可。

二、Recycle_bin詳細說明

編譯/下載/安裝/卸載

可以通過下載源碼編譯,或者直接下載庫文件

源碼編譯

源碼編譯依賴MySQL源代碼,推薦使用5.7.18以上的版本進行編譯。

git clone [email protected]:sunashe/MySQL-Plugin-Recycle-Bin.git
cp -r MySQL-Plugin-Recycle-Bin  mysql_source_dir/plugin/
cd mysql_source_dir
cmake . -DBUILD_CONFIG=mysql_release -DDOWNLOAD_BOOST=1  -DWITH_BOOST=/usr/local/boost/
cd plugin/MySQL-Plugin-Recycle-Bin
make 
#拷貝當前目錄下的recycle_bin.so到MySQL中配置的plugin_dir下。

下載編譯好的lib文件

下載頁面
https://github.com/sunashe/MySQL-Plugin-Recycle-Bin/releases

安裝插件

mysql> install plugin recycle_bin soname 'recycle_bin.so';
Query OK, 0 rows affected (0.02 sec)

查看MySQL錯誤日誌,如果出現如下內容,則證明安裝成功

2019-02-20T19:52:27.326951+08:00 22 [Note] Install Plugin 'recycle_bin' successfully.

卸載插件

mysql> uninstall plugin recycle_bin;
Query OK, 0 rows affected (0.02 sec)

參數說明

  • recycle_bin_enabled
    全局控制操作,ON表示開啓recycle_bin的功能,在recycle_bin準備就緒後,會自動備份被Drop的表

  • recycle_bin_database_name
    指定回收站庫名,默認爲recycle_bin_dba

  • recycle_bin_expire_seconds
    備份表的過期時間,或者較保留時間,默認爲1800s

  • recycle_bin_check_sql_delay_period
    備份操作時,需要等待所有相關的dml語句回放完成,recycle_bin_check_sql_delay_period用於
    控制判斷週期。默認爲10us.

狀態值

  • Recycle_bin_status
    recycle_bin的工作狀態,recycle_bin_enabled只是一個參數控制,而Recycle_bin_status表示已經符合了條件
    ,正式開始工作。一般只有在接收到master的FD event後纔會正常工作。所以最好在安裝插件後,在master上執行一次flush logs操作
    或者重啓複製IO線程。

使用示例

slave查看當前回收站狀態

mysql> show global status like '%recycle%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| Recycle_bin_status | ON    |
+--------------------+-------+

master上新建測試庫表,插入數據

mysql> use sunashe;
Database changed
mysql> create table t1(id int not null auto_increment primary key,name varchar(10))
    -> ;
Query OK, 0 rows affected (0.02 sec)

mysql> insert into t1(name) values('aaa');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1(name) values('aaa');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1(name) values('aaa');
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+----+------+
| id | name |
+----+------+
|  1 | aaa  |
|  2 | aaa  |
|  3 | aaa  |
+----+------+
3 rows in set (0.00 sec)

slave上查看同步的數據

mysql> use sunashe;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------+
| Tables_in_sunashe |
+-------------------+
| t1                |
+-------------------+
1 row in set (0.01 sec)

mysql> select * from t1;
+----+------+
| id | name |
+----+------+
|  1 | aaa  |
|  2 | aaa  |
|  3 | aaa  |
+----+------+
3 rows in set (0.00 sec)

master上執行drop table操作

mysql> drop table t1;
Query OK, 0 rows affected (0.00 sec)
mysql> show tables;
Empty set (0.00 sec)

此時slave中sunashe庫下的t1表也被刪除了,但是存放在了回收站庫中。

mysql> show tables;
Empty set (0.00 sec)

mysql> show tables in recycle_bin_dba;
+-------------------------------------+
| Tables_in_recycle_bin_dba           |
+-------------------------------------+
| db1_t1_ashesun_1550664699603202     |
| sunashe_t1_ashesun_1550664941582282 |
+-------------------------------------+

//錯誤日誌
2019-02-20T20:15:41.581959+08:00 23 [Note] Master drop table sunashe.t1
2019-02-20T20:15:41.610112+08:00 23 [Note] Backup table sunashe.t1 successfully.
2 rows in set (0.00 sec)

表名格式爲原庫名_原表名_時間flag_unix時間戳(us),查詢備份數據正確性

mysql> select * from recycle_bin_dba.sunashe_t1_ashesun_1550664941582282;
+----+------+
| id | name |
+----+------+
|  1 | aaa  |
|  2 | aaa  |
|  3 | aaa  |
+----+------+
3 rows in set (0.01 sec)

備份數據過期後,在業務低峯期時(收到心跳event),自動清除。關聯參數recycle_bin_expire_seconds.

mysql> set global recycle_bin_expire_seconds=10;
Query OK, 0 rows affected (0.01 sec)

mysql> show tables in recycle_bin_dba;
+-------------------------------------+
| Tables_in_recycle_bin_dba           |
+-------------------------------------+
| db1_t1_ashesun_1550664699603202     |
| sunashe_t1_ashesun_1550664941582282 |
+-------------------------------------+
2 rows in set (0.00 sec)

mysql> show tables in recycle_bin_dba;
Empty set (0.00 sec)

查看複製環境是否正常運行

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.211.55.32
                  Master_User: ashe
                  Master_Port: 13307
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 3080
               Relay_Log_File: mysql-relay-bin-master_13307.000004
                Relay_Log_Pos: 3293
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table: mysql.ibbackup_binlog_marker
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table: mysql.backup_%
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 3080
              Relay_Log_Space: 3600
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 12713307
                  Master_UUID: cdfe45e6-c227-11e8-abf5-001c42bf9720
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: cdfe45e6-c227-11e8-abf5-001c42bf9720:708-1419
            Executed_Gtid_Set: cdfe45e6-c227-11e8-abf5-001c42bf9720:1-1419
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name: master_13307
           Master_TLS_Version:
1 row in set (0.01 sec)

recycle_bin的備份清除等操作不會記錄任何binlog信息,保證和master的GTID一致。

其它使用說明

  • 複製必須開啓GTID,即MySQL參數gtid_mode=on
  • 支持異步或者半同步複製,對於異步複製來講,不會影響master的性能,對於半同步複製來講,對master有5%左右的性能損失。
  • 可以通過手動drop table的方式清除recycle_bin_dba下的備份表。
  • 由於備份表的表名格式爲原庫名_原表名_時間flag_unix時間戳(us),所以庫名+表名最長不能超過(64-16(us)-7(flag))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章