基本上每個跟資料庫打交道的程式設計師(當然也可能是你同事)都會碰乙個問題,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...