背景:
業務須要恢復一段時間內對某個表的全部DELETE記錄,過濾UPDATE、INSERT操做,測試發現 MariaDB的flashback命令會閃回對錶的全部dml操做,沒法知足業務需求。調研三方工具測試發現binlog2sql能夠實現生成原始SQL、回滾SQL、去除主鍵的INSERT SQL。
binlog2sql介紹:
由大衆點評開源的一個 MySQL 閃回工具
用途
- 數據回滾
- 主從切換後數據不一致的修復
- 從 binlog 生成標準 SQL,帶來的衍生功能
閃回原理簡析
閃回原理,因爲 MySQL binlog 以 event 爲單位,記錄數據庫的變動信息,這些信息可以幫助咱們重現這之間的全部變化,也就是所謂的閃回。mysql
binlog 有三種可選的格式:git
- statement:基於 SQL 語句的模式,binlog 數據量小,可是某些語句和函數在複製過程可能致使數據不一致甚至出錯;
- mixed:混合模式,根據語句來選用是 statement 仍是 row 模式;
- row:基於行的模式,記錄的是行的完整變化。安全,但 binlog 會比其餘兩種模式大不少;
利用 binlog 作閃回,須要將 binlog 格式設置爲 row,由於咱們須要最詳盡的信息來肯定操做以後數據不會出錯。github
既然 binlog 以 event 形式記錄了全部的變動信息,那麼咱們把須要回滾的 event,從後往前回滾回去便可sql
回滾操做:數據庫
- 對於 delete 操做,咱們從 binlog 提取出 delete 信息,反向生成 insert 回滾語句;
- 對於 insert 操做,反向生成 delete 回滾語句;
- 對於 update 操做,根據信息生成反向的 update 語句;
- mysql 服務必須開啓,離線模式下不能解析
- 參數 binlog_row_image 必須爲FULL,暫不支持MINIMAL
- 解析速度不如mysqlbinlog
- 優勢(對比mysqlbinlog)
- 純Python開發,安裝與使用都很簡單
- 自帶flashback、no-primary-key解析模式,無需再裝補丁
- flashback模式下,更適合閃回實戰
- 解析爲標準SQL,方便理解、篩選
- 代碼容易改造,能夠支持更多個性化解析
官方測試環境:
Python2.七、3.4+
MySQL5.六、5.七、MariaDB 10.2.11(自測)
安裝:
pip install -r requirements.txt
MySQL服務設置
binlog必須開啓
binlog格式必須爲row格式
binlog_row_image = full 由於須要解析具體行更新先後的變化,因此必須設置爲full
鏈接用戶權限:
select, super/replication client, replication slave
建議受權
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO
權限說明
select:須要讀取server端information_schema.COLUMNS表,獲取表結構的元信息,拼接成可視化的sql語句
super/replication client:兩個權限均可以,須要執行'SHOW MASTER STATUS', 獲取server端的binlog列表
replication slave:經過BINLOG_DUMP協議獲取binlog內容的權限
基本用法:
解析標準SQL:
解析回滾SQL:
鏈接配置選項
mysql鏈接配置api
-h host; -P port; -u user; -p password安全
解析模式app
--stop-never 持續解析binlog。可選。默認False,同步至執行命令時最新的binlog位置。函數
-K, --no-primary-key 對INSERT語句去除主鍵。可選。默認False工具
-B, --flashback 生成回滾SQL,可解析大文件,不受內存限制。可選。默認False。與stop-never或no-primary-key不能同時添加。
--back-interval -B模式下,每打印一千行回滾SQL,加一句SLEEP多少秒,如不想加SLEEP,請設爲0。可選。默認1.0。
解析範圍控制
--start-file 起始解析文件,只需文件名,無需全路徑 。必須。
--start-position/--start-pos 起始解析位置。可選。默認爲start-file的起始位置。
--stop-file/--end-file 終止解析文件。可選。默認爲start-file同一個文件。若解析模式爲stop-never,此選項失效。
--stop-position/--end-pos 終止解析位置。可選。默認爲stop-file的最末位置;若解析模式爲stop-never,此選項失效。
--start-datetime 起始解析時間,格式'%Y-%m-%d %H:%M:%S'。可選。默認不過濾。
--stop-datetime 終止解析時間,格式'%Y-%m-%d %H:%M:%S'。可選。默認不過濾。
對象過濾
-d, --databases 只解析目標db的sql,多個庫用空格隔開,如-d db1 db2。可選。默認爲空。
-t, --tables 只解析目標table的sql,多張表用空格隔開,如-t tbl1 tbl2。可選。默認爲空。
--only-dml 只解析dml,忽略ddl。可選。默認False。
--sql-type 只解析指定類型,支持INSERT, UPDATE, DELETE。多個類型用空格隔開,如--sql-type INSERT DELETE。可選。默認爲增刪改都解析。用了此參數但沒填任何類型,則三者都不解析。
測試
環境:Python2.7.8 MariaDB10.2.11
t1 表T1時刻 原始數據:
t1表T2時刻日後分別刪除插入記錄:
業務恢復需求:
將數據恢復至T1時刻,可是T1-T2這段時間的INSERT數據不須要恢復,只恢復DELETE的數據(即恢復id=2和3 的記錄)
方法1:MariaDB flashback
/usr/local/mariadb/bin/mysqlbinlog --start-datetime='2019-06-05 18:49:37' -d test -T t1 hf_test-bin.000131 --flashback >recover.sql
能夠生成對應的回滾語句,可是包含此表這段時間的全部dml操做,單純過濾出DELETE操做出錯率高,可靠性差
方法2:binlog2sql
解析這段時間對此表的dml操做
生成回滾SQL
過濾文件中業務須要的INSERT語句:
恢復:myin 3308 test <./insert.sql
T1後插入的 dd ,ee 記錄保留,刪除的bb,cc 恢復完成!
總結:
業務方會根據各類場景提各類奇葩需求,須要DBA根據具體狀況具體分析,多測試,才能作到駕輕就熟
MariaDB的flashback頗有效,但針對此需求binlog2sql更適合,具體需求具體分析