binlog2sql與Myflash

一、場景

       一般情況下,數據表被誤操作,通常都會使用 備份+binlog 進行恢復。那如果誤操作爲dml而不是ddl,並且操作的語句不多,這樣的話使用該方式會極大的影響業務,這就造成一個痛點:少量數據不恢復不行,恢復又極大的影響線上業務。這時binlog2sql應運而生,但是使用binlog2sql恢復會比較慢,這時Myflash 也就隨之出現。具體應該使用哪一個下文會進行優缺點分析。

二、閃回原理

        在此就不說明binlog是什麼,怎麼工作,內容的含義了(因爲這是寫給我自己看的-<->-)

        每個工具實現閃回的方式都不同,但是有一點是一樣的:

                   insert ----> delete ; delete -----> insert; update---->將set 和 where置換

        binlog2sql是作爲通過python-mysql-replication將自己作爲僞slave讀取binlog並將dml轉換之後讀取系統表TABLES,從而轉換成標準的SQL語句。

        myflash是直接解析binlog文件並將其轉換,所以速度要快得多,使用此工具pos一定要找準。

三、工具介紹

       到現在爲止一般會有4種方法對binlog進行處理:

1.mysqlbinlog 工具配合 sed、awk
    此方法比較簡單,但是做起來還是比較複雜的,尤其是字段類型比較大的時候
2.給數據庫源碼打patch
    mysql5.5的mysqlbinlog應該有flashback選項。這種方法需要對數據庫源碼非常熟悉並且善於編程的大佬。這種方法升級版本的話就不適用了,所以運維成本非常大。
3.binlog2sql
    對SQL進行構造,穩定性好,上手難度低,效率也低。
4.myflash
    

四、binlog2sql 安裝

前提:

MySQL server 必須設置以下參數:

[mysqld]

server_id=1

log_bin=/wx/mydata/mysql-bin.log

max_binlog_size=1G

binlog_format=row

binlog_row_image=full

1.版本
python2.7  ,  python 3.4+ 
mysql 5.6 、 5.7
2.安裝python(2.7建議)
    # wget https://www.python.org/downloads/release/python-371/Python-3.7.1.tgz
    yum install libffi-devel  openssl openssl-devel(去網上下載rpm包)
    安裝pip:略
3.下載binlog2sql
    git clone https://github.com/danfengcao/binlog2sql.git
4.安裝binlog2sql
    sudo /usr/local/bin/pip  install --no-index  --find-links="./packages/" -r requirements.txt
    packages可在https://download.csdn.net/download/wangxin3618/10883140 下載;也可自己製作
    連網環境:pip install -r requirements.txt
pip安裝:
    python2.7 安裝pip
1 先安裝setuptools
   下載地址:https://pypi.python.org/pypi/setuptools#downloads
 將下載後的tar文件解壓,用CMD模式進入到解壓後的文件所在的目錄執行命令:python setup.py install
2 安裝pip 
 下載地址:https://pypi.python.org/pypi/pip#downloads
   將下載後的tar文件解壓,用CMD模式進入到解壓後的文件所在的目錄執行命令:python setup.py install 
 安裝完成

五、binlog使用測試

使用:

1.DDL (truncate)語句,在整個過程中都是無法輸出的
2.表刪了,就不能解析出dml語句了,需將表創建後才能使用
3.文件可以是動態的(正在被追加的文件)
4.可解析大文件,不受內存限制。是否可以將一個binlog文件分成多個小文件處理???NO
5.mysql server 必須開啓,離線(關閉)模式下不能解析
6.參數binlog_row_image 必須爲full,暫不支持MINIMAL
7.解析速度不理想,不如myflash
8.純python開發,安裝使用很簡單
9.自帶flashback、no-primary-key解析模式,無需安裝補丁
10.如果只回滾某張表,並且該表有關聯表,關聯表不會被回滾

用途:

1.數據快速回滾(閃回)
2.主從切換後新master丟數據的修復
3.從binlog生成標準SQL

binlog2sql解析原理:

通過binlog_dump 協議來獲取binlog內容,需要讀取information_schema.columns表來獲取元信息,這樣才能結合binlog拼接成SQL語句。所以給出用戶的最小權限:GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'user'@'%';
權限說明:
select:需要讀取server端information_schema.COLUMNS表,獲取表結構的元信息,拼接成可視化的sql語句
super/replication client:兩個權限都可以,需要執行'SHOW MASTER STATUS', 獲取server端的binlog列表
replication slave:通過BINLOG_DUMP協議獲取binlog內容的權限
用python-mysql-replication實現了MySQL的複製協議,該服務僞裝成mysql slave,來獲取主的binlog和event。
如果在高併發環境上解析binlog,相當於多了一個同步線程在主上讀取數據,這就加大了主的負擔。

binlog2sql參數:

解析模式
--stop-never : 持續解析binlog。可選。默認false,同步至執行命令時最新的binlog位置,如果不ctrl+c就不會退出。
--no-primariy-key , -K : 對insert語句去除主鍵。可選。默認false
--flashback,-B : 生成回滾SQL,可解析大文件,不受內存限制。可選。默認false。與stop-never或no-primary-key 不能同時使用。
--back-interval -B 模式下,每打印一千行回滾SQL,加一句sleep多少秒,如果不想加sleep,請設爲0.
解析範圍控制
--start-file : 起始解析文件,只需要文件名,無需全路徑。必須。
--stop-file :  終止解析文件,可選。默認和stat-file同一個文件。若解析模式爲stop-server ,則該選項失效。
--start-position / --start-pos : 起始解析位置。可選,默認爲start-file的起始位置
--stop-position / --stop-pos : 終止解析位置。可選。默認爲stop-file的最末位置。若解析模式爲stop-server ,則該選項失效。
--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 table1 table2 。可選默認爲空
--only-dml  只解析dml,忽略ddl。可選默認false。在打印誤刪語句的時候會將ddl語句也打印出來,這時加上該選項則只打印dml。在flashback的時候不管加沒加這個參數,都只打印dml。
--sql-type 只解析指定類型,支持insert,update,delete。多個類型用空格隔開:--sql-type insert delete .可選。默認dml都解析。用了此參數但沒有填任何類型,則三者都不解析。在打印誤操作語句的時候指定該參數則打印指定的類型如:指定insert就打印insert;在打印回滾語句的時候指定該參數則打印與之相反的類型如:指定insert,則打印delete;

使用方法:

首先判斷誤刪語句所在的binlog文件:show master status; or 去binlog dir ll 查看binlog file的最後修改時間來確定

其次確定誤刪語句執行的大致時間:詢問執行該語句的人

然後指定文件與時間和對應的庫表做一次大致的篩選,然後再通過position篩選出需要回滾的數據(也可以查找binlog文件直接確定誤操作語句的準確pos)

sudo python /wx/binlog2sql/binlog2sql/binlog2sql.py  -uroot -h10.124.202.125  -p -P3306 --sql-type delete  --only-dml   -dtest -t table1 table2 --start-file='mysql-bin.000008'
sudo python /wx/binlog2sql/binlog2sql/binlog2sql.py --flashback  -uroot -h10.124.202.125  -p -P3306  --sql-type delete  --only-dml  -dtest -t table1 table2 --start-file='mysql-bin.000008'
sudo python /wx/binlog2sql/binlog2sql/binlog2sql.py --flashback  -uroot -h10.124.202.125  -p -P3306 --sql-type delete  --only-dml  -dtest -t table1 table2 --start-file='mysql-bin.000008'| mysql -uroot -h10.124.202.125  -p -P3306

六、myflash安裝

安裝依賴包
    yum install gcc*  pkg-config glib2 libgnomeui-devel -y
下載
    git clone https://github.com/Meituan-Dianping/MyFlash.git
動態編譯
    gcc -w -g `pkg-config --cflags  glib-2.0` source/binlogParseGlib.c   -o    binary/flashback /lib64/libglib-2.0.so.0
步驟:
    1.首先flush logs;使誤操作的binlog所在的log文件成爲靜態的
    2.根據誤操作的時間點和語句,通過mysqlbinlog |grep -i <dml>  -C20 分析出誤操作確定    的pos ;
    3.然後生成回滾後的binlog  
    4.再將binlog導入到mysql server中
測試
    mysql> flush logs;
    shell> mysqlbinlog  -vv --base64-output=decode-rows --start-datetime='2018-12-26 10:00:00' --database=test   mysql-bin.000008|grep -i -C20 delete 
    shell> sudo ../binary/flashback  --binlogFileNames=/wx/mydata/data1/binlog/mysql-bin.000008 --databaseNames=test  --tableNames=table3  --sqlTypes='delete'  --start-position=7955  --stop-position=8177  
    shell> sudo mysqlbinlog    --skip-gtids     binlog_output_base.flashback  |/wx/mysql/bin/mysql -uroot -p -S /wx/mydata/data1/mysql.sock

測試問題:
1.在開啓gtid的MySQL server上,應用flashback報錯,錯誤爲:ERROR 1782 (HY000) at line 16: @@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON. 
    答:在導入時加入--skip-gtids mysqlbinlog --skip-gtids | mysql -uxxx -pxxx
2.如果回滾後的binlog日誌尺寸超過20M,在導入時,很耗時。如何處理?
    答:參考 使用 ,搜索maxSplitSize。使用該參數可以對文件進行切片
3.加入 sqlTypes  ,會將原delete語句反轉成insert語句

myflash 靜態編譯和動態編譯:

動態編譯鏈接
    gcc -w  `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c  -o binary/flashback
    然而用戶不想每次去重新編譯,可以選擇使用靜態鏈接,但是該方法需要知道glib庫的版本和位置,因此對於每臺機器略有不同,請謹慎使用

靜態編譯鏈接
    爲了保證在一臺機器上編譯後,可以在其它機器上使用,需要滿足以下兩個條件 
        a) 將glib做成靜態鏈接 
        b)在編譯的那臺機器的glibc版本(查看方法爲ldd --version)要小於等於要運行該軟件的那臺機器glibc版本 因此需要你在一臺glibc版本較低的機器上運行如下命令即可。
    gcc -w -g `pkg-config --cflags  glib-2.0` source/binlogParseGlib.c   -o binary/flashback /usr/lib64/libglib-2.0.a -lrt

七、myflash使用

使用:

1.解析的binlog文件需爲靜態的(解析過程中binlog不能再寫入):儘量 flush logs 之後再分析
2.可以處理離線的binlog文件(該binlog文件對應的mysql server 可以是關閉的)

限制:

binlog格式必須爲row,且binlog_row_image=full
僅支持5.6與5.7
只能回滾DML(增、刪、改)

參數說明:

1.databaseNames 
指定需要回滾的數據庫名。多個可用‘,’隔開。不指定該參數則指定所有的庫
2.tableNames
指定需要回滾的表名。多個可用‘,’隔開。不指定該參數則指定所有的表
3.start-position
指定回滾開始的位置,如不指定則從文件的開始處回滾
4.stop-position 
指定回滾結束的位置,如不指定則回滾到文件結尾
5.start-datetime
指定回滾的開始時間,格式爲 %Y-%m-%d %H:%M:%S。 如不指定,則不限定時間
6.stop-datetime
指定回滾的結束時間。注意格式必須是 %Y-%m-%d %H:%M:%S。 如不指定,則不限定時間
7.sqlTypes
指定需要回滾的sql類型。目前支持的過濾類型是INSERT, UPDATE ,DELETE。多個類型可以用“,”隔開。
8.maxSplitSize
一旦指定該參數,對文件進行固定尺寸的分割(單位爲M)。防止單次應用的binlog尺寸過大。指定一個文件多少兆。
9.loglevel 	
僅開發者使用,默認級別爲error級別。在生產環境中不要修改這個級別,竇澤會輸出過多
10.include-gtids
指定需要回滾的gtid,支持gtid的單個和範圍兩種形式。
11.exclude-gtids
指定不需要回滾的gtid,用法同include-gtids

解析的不同:

與binlog2sql的解析方法不同:
binlog2sql:
    1.binlog2sql 是先根據過濾條件將 操作的可視化語句 顯示出來(每條語句後面包含該語句執行的時間與pos)
    2.再根據pos將確定的語句回滾,將回滾後的語句導入到一個SQL文件,然後導入進mysql
flashback:
    1.根據條件直接將binlog反轉:可能反轉出的不僅僅是誤刪的語句,這就需要查看原binlog文件確定誤操作語句的準確pos。如果binlog文件很大,則查找很費力。但是binlog2sql解析很慢。

八、兩種工具性能對比

表:

CREATE TABLE `flash_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nameShort` varchar(20) DEFAULT NULL,
  `nameLong` varchar(260) DEFAULT NULL,
  `amount` decimal(19,9) DEFAULT NULL,
  `amountFloat` float DEFAULT NULL,
  `amountDouble` double DEFAULT NULL,
  `createDatetime6` datetime(6) DEFAULT NULL,
  `nameText` text,
  `nameBlob` blob,
  `nameMedium` mediumtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=876527 DEFAULT CHARSET=utf8

rows:100萬; binlog文件大小:400M

生成反轉語句:

         myflash:binlog2sql = 1:8

將反轉語句導入到mysql:

         myflash:binlog2sql = 1:15

總結:從恢復速度上面 myflash 遠優於 binlog2sql

myflash可處理離線binlog文件,並支持拆分,但是文件需是靜態的

binlog2sql 可處理動態文件,但是server須存活

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章