MYSQL資料回滾

2021-08-31 18:32:53 字數 3950 閱讀 7602

基本上每個跟資料庫打交道的程式設計師(當然也可能是你同事)都會碰乙個問題,mysql誤操作後如何快速回滾?比如,delete一張表,忘加限制條件,整張表沒了。假如這還是線上環境核心業務資料,那這事就鬧大了。誤操作後,能快速回滾資料是非常重要的。

binlog2sql快速回滾

首先,確認你的mysql server開啟了binlog,設定了以下引數:

[mysqld]  server-id = 1  log_bin = /var/log/mysql/mysql-bin.log  max_binlog_size = 1000m  binlog-format = row
如果沒有開啟binlog,也沒有預先生成回滾sql,那真的無法快速回滾了。對存放重要業務資料的mysql,強烈建議開啟binlog。

隨後,安裝開源工具binlog2sql。binlog2sql是一款簡單易用的binlog解析工具,其中乙個功能就是生成回滾sql。

git clone   pip install -r requirements.txt
然後,我們就可以生成回滾sql了。

背景:誤刪了test庫f表整張表的資料,需要緊急回滾。

原有資料

mysql> select * from f;  +-----+-----+---------------------+  | uid | did | updatetime     |  +-----+-----+---------------------+  |  1 | 18 | 2016-12-06 12:28:18 |  |  2 | 19 | 2016-12-06 12:55:56 |  |  3 | 20 | 2016-12-07 14:00:58 |  |  4 | 21 | 2016-12-07 14:01:00 |  +-----+-----+---------------------+  誤操作mysql> delete from f;query ok, 4 rows affected (0.00 sec)  f表被清空  mysql> select * from f;  empty set (0.00 sec)
回滾步驟:

登入mysql,檢視目前的binlog檔案

mysql> show master logs;  +------------------+-----------+  | log_name     | file_size |  +------------------+-----------+  | mysql-bin.000001 | 12262268 |  | mysql-bin.000002 |  132776 |  +------------------+-----------+
最新的binlog檔案是mysql-bin.000002,我們再定位誤操作sql的binlog位置

$ python binlog2sql/binlog2sql.py -h127.0.0.1 -p3306 -uadmin -p'admin' -dtest -t f --start-file='mysql-bin.000002'
輸出:

delete from `test`.`f` where `did`=18 and `updatetime`='2016-12-06 12:28:18' and `uid`=1 limit 1; #start 4 end 314  delete from `test`.`f` where `did`=19 and `updatetime`='2016-12-06 12:55:56' and `uid`=2 limit 1; #start 4 end 314  delete from `test`.`f` where `did`=20 and `updatetime`='2016-12-07 14:00:58' and `uid`=3 limit 1; #start 4 end 314  delete from `test`.`f` where `did`=21 and `updatetime`='2016-12-07 14:01:00' and `uid`=4 limit 1; #start 4 end 314
生成回滾sql,並檢查回滾sql是否正確

$ python binlog2sql/binlog2sql.py -h127.0.0.1 -p3306 -uadmin -p'admin' -dtest -t f --start-file='mysql-bin.000002' --start-pos=4 --end-pos=314 -b
輸出:

insert into `test`.`f`(`did`, `updatetime`, `uid`) values (21, '2016-12-07 14:01:00', 4); #start 4 end 314  insert into `test`.`f`(`did`, `updatetime`, `uid`) values (20, '2016-12-07 14:00:58', 3); #start 4 end 314  insert into `test`.`f`(`did`, `updatetime`, `uid`) values (19, '2016-12-06 12:55:56', 2); #start 4 end 314  insert into `test`.`f`(`did`, `updatetime`, `uid`) values (18, '2016-12-06 12:28:18', 1); #start 4 end 314
確認回滾sql正確,執行回滾語句。登入mysql,資料回滾成功。

$ python binlog2sql.py -h127.0.0.1 -p3306 -uadmin -p'admin' -dtest -t f --start-file='mysql-bin.000002' --start-pos=4 --end-pos=314 -b | mysql -h127.0.0.1 -p3306 -uadmin -p'admin'  mysql> select * from f;  +-----+-----+---------------------+  | uid | did | updatetime     |  +-----+-----+---------------------+  |  1 | 18 | 2016-12-06 12:28:18 |  |  2 | 19 | 2016-12-06 12:55:56 |  |  3 | 20 | 2016-12-07 14:00:58 |  |  4 | 21 | 2016-12-07 14:01:00 |  +-----+-----+---------------------+
至此,不用再擔心被炒魷魚了。

常見問題

有人會問,我ddl誤操作了怎麼快速回滾?比如drop了一張大表。
很難做到。因為即使在在row模式下,ddl操作也不會把每行資料的變化記錄到binlog,所以ddl無法通過binlog回滾。實現ddl回滾,必須要在執行ddl前先備份老資料。確實有人通過修改mysql server原始碼實現了ddl的快速回滾,我找到阿里的xiaobin lin提交了乙個patch。但據我所知,國內很少有網際網路公司應用了這個特性。原因的話,我認為最主要還是懶的去折騰,沒必要搞這個低頻功能,次要原因是會增加一些額外儲存。

所以,ddl誤操作的話一般只能通過備份來恢復。如果公司連備份也不能用了,那真的建議去買張飛機票了。幹啥?跑唄

mysql除了binlog2sql,是否還有其他回滾工具?
當然有。阿里彭立勛對mysqlbinlog增加了flashback的特性,這應該是mysql最早有的flashback功能,彭解決的是dml的回滾,並說明了利用binlog進行dml閃回的設計思路。ddl回滾特性也是由阿里團隊提出並實現的。這兩個功能是有創新精神的,此後出現的閃回工具基本都是對上面兩者的模仿。另外,去哪兒開源的inception是一套mysql自動化運維工具,這個就比較重了,支援dml回滾,還不是從binlog回滾的,是從備份回滾的,也支援ddl回滾表結構,資料是回滾不了滴~

摘自:

mysql回滾命令 關於MySQL回滾機制

在事務中,每個正確的原子操作都會被順序執行,直到遇到錯誤的原子操作,此時事務會將之前的操作進行回滾。回滾的意思是如果之前是插入操作,那麼會執行刪 除插入的記錄,如果之前是update操作,也會執行update操作將之前的記錄還原 因此,正確的原子操作是真正被執行過的。是物理執行。在當前事務中確實能看...

mysql恢復和回滾資料

資料庫不小心刪除或者表不小心刪除,通過mysql恢復的話需要確保刪除前是mysql是開啟binlog。具體步驟 1.查詢binlog狀態以及位置。在 etc my.cfg檢視binlog開啟狀態 可以看到binlog開始狀態是開啟的。2.mysql查詢執行的binlog檔案。目標檔案是mysql b...

關於回滾,mysql

假如銀行中轉帳的時候,如果乙個地方的錢已經發出去了,而另外乙個地方突然停最,那麼這樣就會造成一種情況就是轉帳失敗了,那到怎麼處理這種情況了呢,做乙個簡單的刪除兩個表中的內容來說乙個 conn new mysqli localhost username 123 mydata conn query se...