MySQL資料庫誤操作後快速回滾的方法

2022-09-25 23:21:09 字數 3958 閱讀 8613

基本上每個跟資料庫打交道的程式設計師(當然也可能是你同事)都會碰乙個問題,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。binlog2程式設計客棧sql是一款簡單易用的binlog解析工具,其中乙個功能就是生成回滾sql。

git clone

pip install -r requirements.txt

然後,我們就可以生成回滾sql了。

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

原有資料

mysql> select * from f;

+-----+-----+--------oyieh-------------+

| 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:5oyieh6', 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

確認回滾sqloyieh正確,執行回滾語句。登入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 |

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

至此,不用再擔心被炒魷魚了。

常見問題

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

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

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

本文標題: mysql資料庫誤操作後快速回滾的方法

本文位址:

快速回顧 MySQL 簡單查詢操作

前提要述 參考書籍 mysql必知必會 為了查詢出資料庫表中的行 資料 使用selece語句。格式 第一種 select from 第二種 select field1,field2,from 例如 select stu name from student select stu name,stu fr...

MySQL快速回顧 高階查詢操作

檢索出的資料並不是以純粹的隨機順序顯示的。如果不排序,資料一般將以它在底層表 現的順序顯示。這可以是資料最初新增到表中的順序。但是,如果資料後來進行過更新或刪除,則此順序將會受到mysql重用 儲存空間的影響。因此,如果不明確控制的話,不能依賴該排序順序。關聯式資料庫設計理論認為,如果不明確規定排序...

資料庫在誤操作下,日誌恢復

在使用了updata,delete,或者其他情況讓資料庫遭到破壞時,可以使用下列方法進行恢復,前提是要有上次的備份,並且要對現在資料庫的日誌進行備份。遇到資料庫誤操作的時候,千萬別著急,不要用上次的備份直接恢復資料庫,這樣導致日誌也被覆蓋。具體操作,看下面的例子 前提條件 mybbs是資料庫test...