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
三、限制
- binlog格式必須為row,且binlog_row_image=full
- 僅支援5.6與5.7
- 只能回滾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】利用binlog回滾DML操作
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 { }