1. 程式人生 > >MyFlash-DML回滾工具

MyFlash-DML回滾工具

一、簡介

MyFlash是由美團點評公司技術工程部開發維護的一個回滾DML操作的工具。該工具通過解析v4版本的binlog,完成回滾操作。相對已有的回滾工具,其增加了更多的過濾選項,讓回滾更加容易

二、安裝

安裝環境:centos7 64位

cd /usr/local

cd MyFlash

#動態編譯:

gcc -w  `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c  -o binary/flashback

三、限制

  1. binlog格式必須為row,且binlog_row_image=full
  2. 僅支援5.6與5.7
  3. 只能回滾DML(增、刪、改)

四、使用

    引數:

./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

下面的這些引數是可以任意組合的。

  • 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檔案切割,防止單次應用的binlog尺寸過大,對線上造成壓力

  • 9.binlogFileNames

    指定需要回滾的binlog檔案,目前只支援單個檔案,後續會增加多個檔案支援

  • 10.outBinlogFileNameBase

    指定輸出的binlog檔案字首,如不指定,則預設為binlog_output_base.flashback

  • 11.logLevel

    僅供開發者使用,預設級別為error級別。在生產環境中不要修改這個級別,否則輸出過多

  • 12.include-gtids

    指定需要回滾的gtid,支援gtid的單個和範圍兩種形式。

  • 13.exclude-gtids

    指定不需要回滾的gtid,用法同include-gtids

回滾測試:

表結構:

mysql> show create table t1\G

*************************** 1. row ***************************

       Table: t1

Create Table: CREATE TABLE `t1` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(32) NOT NULL,

  `tel` varchar(16) NOT NULL DEFAULT '15800377643' COMMENT '手機號',

  PRIMARY KEY (`id`),

  KEY `idx_name` (`name`)

) ENGINE=InnoDB AUTO_INCREMENT=8000001 DEFAULT CHARSET=utf8

1 row in set (0.01 sec)

mysql> select count(*) from t1;

+----------+

| count(*) |

+----------+

|  7279195 |

+----------+

1 row in set (2.46 sec)

mysql> show binary logs;

+------------------+-----------+

| Log_name         | File_size |

+------------------+-----------+

| mysql-bin.000001 |       201 |

| mysql-bin.000002 |       201 |

| mysql-bin.000003 |       201 |

| mysql-bin.000004 | 131034361 |

| mysql-bin.000005 |       201 |

| mysql-bin.000006 |       201 |

| mysql-bin.000007 |       480 |

| mysql-bin.000008 |  35610031 |

+------------------+-----------+

8 rows in set (0.00 sec)

誤刪除測試:

mysql> flush logs;

Query OK, 0 rows affected (0.02 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> delete from t1 where id>3000000;

Query OK, 4919909 rows affected (5 min 0.48 sec)  #測試機器配置爛啊沒辦法

mysql> commit;

Query OK, 0 rows affected (0.39 sec)

mysql> show binary logs;

+------------------+-----------+

| Log_name         | File_size |

+------------------+-----------+

| mysql-bin.000001 |       201 |

| mysql-bin.000002 |       201 |

| mysql-bin.000003 |       201 |

| mysql-bin.000004 | 131034361 |

| mysql-bin.000005 |       201 |

| mysql-bin.000006 |       201 |

| mysql-bin.000007 |       480 |

| mysql-bin.000008 |  35610078 |

| mysql-bin.000009 |  93879160 |

+------------------+-----------+

9 rows in set (0.01 sec)

#開始恢復被delete的資料

[[email protected] binary]# time ./flashback --binlogFileNames=/data/mysql/3306/logs/mysql-bin.000009 --sqlTypes=DELETE

real0m0.738s

user0m0.286s

sys0m0.440s

[[email protected] binary]# du -sh *

90Mbinlog_output_base.flashback

48Kflashback

6.6Mmysqlbinlog20160408

將delete轉換成insert的速度超級快啊,有木有。

由於binlog_output_base.flashback有90M所以需要將其進行切片,讓匯入到mysql的速度更加快

 ./flashback --maxSplitSize=20 --binlogFileNames=binlog_output_base.flashback 

[[email protected] binary]# ll

total 190776

-rw-r--r-- 1 root root 20977983 Nov 23 15:48 binlog_output_base.000001

-rw-r--r-- 1 root root 20977983 Nov 23 15:48 binlog_output_base.000002

-rw-r--r-- 1 root root 20977983 Nov 23 15:48 binlog_output_base.000003

-rw-r--r-- 1 root root 20977983 Nov 23 15:48 binlog_output_base.000004

-rw-r--r-- 1 root root 10585292 Nov 23 15:48 binlog_output_base.000005

-rw-r--r-- 1 root root 93878918 Nov 23 15:46 binlog_output_base.flashback

-rwxr-xr-x 1 root root    48888 Nov 17 13:59 flashback

-rwxr-xr-x 1 root root  7463125 Nov 17 13:56 mysqlbinlog20160408

#分別將1 2 3 4 5匯入資料庫:

[[email protected] binary]# mysqlbinlog binlog_output_base.000001 |mysql --login-path=wangxin

ERROR 1782 (HY000) at line 17: @@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.

出現了報錯。由於檔案裡面的GTID值在binlog裡面已經存在了,所以需要關閉主庫的GTID

或者使用--skip-gtids引數

1、mysqlbinlog --skip-gtids binlog_output_base.000001 |mysql --login-path=wangxin

2、

mysql> set global GTID_MODE = ON_PERMISSIVE;

Query OK, 0 rows affected (0.01 sec)

mysql> set global GTID_MODE = OFF_PERMISSIVE;

Query OK, 0 rows affected (0.00 sec)

mysql> set global GTID_MODE = OFF;

Query OK, 0 rows affected (0.00 sec)

#現在再來匯入:

 mysqlbinlog binlog_output_base.000001 |mysql --login-path=wangxin

 mysqlbinlog binlog_output_base.000002 |mysql --login-path=wangxin

 mysqlbinlog binlog_output_base.000003 |mysql --login-path=wangxin

 mysqlbinlog binlog_output_base.000004 |mysql --login-path=wangxin

 mysqlbinlog binlog_output_base.000005 |mysql --login-path=wangxin

#將主庫GTID重新開啟

mysql> set global GTID_MODE = OFF_PERMISSIVE;

Query OK, 0 rows affected (0.01 sec)

mysql> set global GTID_MODE = ON_PERMISSIVE;

Query OK, 0 rows affected (0.00 sec)

mysql> set global GTID_MODE = ON;

Query OK, 0 rows affected (0.01 sec)

#驗證資料量:

mysql> select count(*) from t1;

+----------+

| count(*) |

+----------+

|  7279195 |

+----------+

1 row in set (2.53 sec)

誤更新測試:

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> update t1 set name='mic' where id > 5000000;

Query OK, 2934501 rows affected (2 min 43.44 sec)

Rows matched: 2934501  Changed: 2934501  Warnings: 0

mysql> commit;

Query OK, 0 rows affected (0.49 sec)

./flashback --binlogFileNames=/data/mysql/3306/logs/mysql-bin.000017 --sqlTypes=UPDATE

#轉換成sql檔案看看內容

mysqlbinlog -v -v --base64-output=decode-rows binlog_output_base.flashback >17.sql

#171123 16:26:29 server id 13306  end_log_pos 117898077 CRC32 0x5a4c3e9e        Update_rows: table id 223 flags: STMT_END_F

### UPDATE `wangxin`.`t1`

### WHERE

###   @1=5000001 /* INT meta=0 nullable=0 is_null=0 */

###   @2='mic' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */

###   @3='15800377643' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */

### SET

###   @1=5000001 /* INT meta=0 nullable=0 is_null=0 */

###   @2='1' /* VARSTRING(96) meta=96 nullable=0 is_null=0 */

###   @3='15800377643' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */

之後的步驟和上面一樣就不演示了,還有insert操作,會轉變為delete

insert操作回滾:

mysql> show create table a\G

*************************** 1. row ***************************

       Table: a

Create Table: CREATE TABLE `a` (

  `a` int(11) DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

mysql> select * from a;

+------+

| a    |

+------+

|    1 |

|    2 |

|    3 |

+------+

3 rows in set (0.00 sec)

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into a values(4);

Query OK, 1 row affected (0.01 sec)

mysql> commit;

Query OK, 0 rows affected (0.01 sec)

./flashback --binlogFileNames=/data/mysql/3306/logs/mysql-bin.000019 --sqlTypes=INSERT

#檢視19.sql 可以看到已經轉變成delete sql了

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;

/*!50003 SET @[email protected]@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

DELIMITER /*!*/;

# at 4

#171123 16:44:49 server id 13306  end_log_pos 123 CRC32 0xf0b4e58c      Start: binlog v 4, server v 5.7.17-log created 171123 16:44:49

# Warning: this binlog is either in use or was not closed properly.

# at 123

#171123 16:45:30 server id 13306  end_log_pos 170 CRC32 0xbdcd839e      Table_map: `wangxin`.`a` mapped to number 221

# at 170

#171123 16:45:30 server id 13306  end_log_pos 210 CRC32 0xc265d3ea      Delete_rows: table id 221 flags: STMT_END_F

### DELETE FROM `wangxin`.`a`

### WHERE

###   @1=4 /* INT meta=0 nullable=1 is_null=0 */

SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;

DELIMITER ;

# End of log file

/*!50003 SET [email protected]_COMPLETION_TYPE*/;

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;


相關推薦

MyFlash-DML工具

一、簡介 MyFlash是由美團點評公司技術工程部開發維護的一個回滾DML操作的工具。該工具通過解析v4版本的binlog,完成回滾操作。相對已有的回滾工具,其增加了更多的過濾選項,讓回滾更加容易 二、安裝 安裝環境:centos7 64位 cd /usr

MySQL工具binlog2sql使用介紹

MySQL回滾binlog2sql使用參數介紹:參考官網地址:https://github.com/danfengcao/binlog2sql 直接從官網下載軟件包,照著github上給的方法,雖然可以安裝成功,但是執行如下命了報錯,由於此工具源代碼是是別人所寫,目前暫時沒找到是代碼的哪個地方導致的語法錯誤。

mysql基於binlog工具_flashback(python版本)

 update、delete的條件寫錯甚至沒有寫,導致資料操作錯誤,需要恢復被誤操作的行記錄。這種情形,其實時有發生,可以選擇用備份檔案+binlog來恢復到測試環境,然後再做資料修復,但是這樣其實需要耗費一定的時間跟資源。     其實,如果binlog format為row,binlog檔案中是會詳

【MySQL】利用binlogDML操作

require shell腳本 table 開發人員 date操作 生成 options root flashback 簡介:數據庫運行過程中難免會發生誤操作,特別是在測試環境 開發人員或測試人員有時會誤刪或者更新錯誤某些數據。這時可以用binlog閃回DML操作。 條件:

Transactional 事務 分析

transactionalSpring的AOP事務管理默認是針對unchecked exception回滾(運行期異常,Runtime Exception)。  unchecked ,就是不用手工寫try catch的exception  Exception作為基類,下面還分checked exception

git到某個版本操作

單機 技術分享 ast ima logs strong .cn master blog git回滾到某個版本操作: 1.git log //查看指過去的版本 2. git reset --hard 復制上面commit後的字符串到此處 如果只想 回滾單機的,那麽到

MySQL表類型MyISAM/InnoDB的區別(解決事務不的問題)(轉)

span into article one 工具 tab select var pan MyISAM:這個是默認類型,它是基於傳統的ISAM類型,ISAM是Indexed Sequential Access Method (有索引的順序訪問方法) 的縮寫,它是存儲記錄和文件

關於oracle實例恢復的前的理解

關於oracle實例恢復的前滾和回滾的理解關於oracle實例恢復的一些理解,一直都有誤區,今天通過查看相關資料和與同學探討,發覺了自己的錯誤,探討結果如下:實例恢復:當數據庫非正常關閉的時候(斷電或者shu abort等等非一致性關閉),當你從新啟動數據庫的時候,數據庫相關進程自動進行實例恢復,無須人工幹

git代碼

而且 有時 分享 eve 目錄 錯誤 會有 9.png 烏龜 有時候我們用git提交代碼後發生了錯誤,代碼沖突了啊等等,我們需要將代碼回到以前的某個版本 git代碼回退有兩種辦法 一、git reset(推薦): 它是將最新的commit刪除,用以前的某個版本的代碼替代最新

mysql的engine不同,導致事物失敗的問題

access mat lte col most heap eight replicat pool 近期在項目上遇到遇到一個頭疼的問題,前方銷售團隊反饋了一個客戶那邊在創建用戶(save object to DB)報錯了以後,前臺展示了錯誤,但是數據庫卻保存了這條記錄。 接

(MYSQL學習筆記4)事務的開啟、提交、

mysql 事務 使用事務要註意以下三點:1、在 MySQL 中只有使用了 Innodb 數據庫引擎的數據庫或表才支持事務。2、事務處理可以用來維護數據庫的完整性,保證成批的 SQL 語句要麽全部執行,要麽全部不執行。3、事務用來管理 insert,update,delete 語句MYSQL 事務處理

Mysql存儲過程中的事務

異常 procedure mysq span val com cnblogs 事務 erro create procedure test(in a int) BEGIN DECLARE t_error INTEGER DEFAULT 0;

Spring 實現部分事務

light back true prop 回滾 sage .class lba aaa 例如有業務需求,在catch異常後,catch塊內把異常的信息存入到數據庫,而catch外的數據全部回滾 try { ....... aaaService.save();

service層中數據異常時

service回滾/**刪除 * @param pd * @throws Exception */ @Transactional(rollbackFor = Exception.class) @Override public void delete(String INCOMINGDISPAT

設置

red 定義變量 結束 dbm 創建 create dbms where lin --創建一個表 create table wan (ename varchar2(6),sex char(2),hiredate date,sal number(8),hun numbe

的意義---JDBC事務探究

final cti span net etc rom tle img round JDBC手動事務提交回滾的常見寫法一直是rollback寫在commit的catch之後: try{ conn.setAutoCommit(false);   ps.execu

spring事務沒

檢查 出現異常 alt clas ransac service info 手動 ons 最近遇見一個問題,用spring管理實務,在service層處理數據,保存數據時出現異常,但沒有回滾,檢查了一下,發現是因為我用try catch將異常進行捕獲了,沒有拋出導

騰訊雲系統盤之後遇到的問題。

bsp gui online 開啟 all 操作 net div 完整 系統:WINDOWS 2012 R2 版本 先是沒有圖形界面。只有一個CMD。由於系統切換到核心界面。使用以下命令。重新開啟圖形界面 需要將核心模式core 變回完整模式 Full,用dism

mybatis 記錄

exception sql this run use mybatis number except 進行 @Transactional public int addThumbsUp(Map map) throws Exception{ int result =

jfinal的

iat urn oid 詳細 clas rri jfinal 成功 margin 有兩種方法 1. @Before(Tx.class) public void test() throws Exception { }