摘要: 利用binlog閃回誤操作數(shù)據(jù)。
基本上每個(gè)跟數(shù)據(jù)庫打交道的程序員(當(dāng)然也可能是你同事)都會(huì)碰一個(gè)問題,MySQL誤操作后如何快速回滾?比如,delete一張表,忘加限制條件,整張表沒了。假如這還是線上環(huán)境核心業(yè)務(wù)數(shù)據(jù),那這事就鬧大了。誤操作后,能快速回滾數(shù)據(jù)是非常重要的。
傳統(tǒng)解法
用全量備份重搭實(shí)例,再利用增量binlog備份,恢復(fù)到誤操作之前的狀態(tài)。然后跳過誤操作的SQL,再繼續(xù)應(yīng)用binlog。此法費(fèi)時(shí)費(fèi)力,不值得再推薦。
利用binlog2sql快速閃回
首先,確認(rèn)你的MySQL server開啟了binlog,設(shè)置了以下參數(shù):
| [mysqld]server-id = 1log_bin = /var/log/mysql/mysql-bin.logmax_binlog_size = 100Mbinlog-format = row | 
如果沒有開啟binlog,也沒有預(yù)先生成回滾SQL,那真的無法快速回滾了。對(duì)存放重要業(yè)務(wù)數(shù)據(jù)的MySQL,強(qiáng)烈建議開啟binlog。
隨后,安裝開源工具binlog2sql。binlog2sql是一款簡單易用的binlog解析工具,其中一個(gè)功能就是生成回滾SQL。
| shell> git clone https://github.com/danfengcao/binlog2sql.gitshell> pip install -r requirements.txt | 
然后,我們就可以生成回滾SQL了。
背景:小明在20點(diǎn)多時(shí)誤刪了test庫tbl表整張表的數(shù)據(jù),需要緊急回滾。
| test庫tbl表原有數(shù)據(jù)mysql> select * from tbl;+----+--------+---------------------+| id | name | addtime |+----+--------+---------------------+| 1 | 小趙 | 2016-12-10 00:04:33 || 2 | 小錢 | 2016-12-10 00:04:48 || 3 | 小孫 | 2016-12-13 20:25:00 || 4 | 小李 | 2016-12-12 00:00:00 |+----+--------+---------------------+4 rows in set (0.00 sec)mysql> delete from tbl;Query OK, 4 rows affected (0.00 sec)20:28時(shí),tbl表誤操作被清空mysql> select * from tbl;Empty set (0.00 sec) | 
恢復(fù)數(shù)據(jù)步驟:
1、登錄mysql,查看目前的binlog文件
| mysql> show master status;+------------------+-----------+| Log_name | File_size |+------------------+-----------+| mysql-bin.000051 | 967 || mysql-bin.000052 | 965 |+------------------+-----------+ | 
2、最新的binlog文件是mysql-bin.000052,我們?cè)俣ㄎ徽`操作SQL的binlog位置。誤操作人只能知道大致的誤操作時(shí)間,我們根據(jù)大致時(shí)間過濾數(shù)據(jù)。
| shell> python binlog2sql/binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -ttbl --start-file='mysql-bin.000052' --start-datetime='2016-12-13 20:25:00' --stop-datetime='2016-12-13 20:30:00'輸出:INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-13 20:25:00', 3, '小孫'); #start 4 end 290 time 2016-12-13 20:25:46INSERT INTO `test`.`tbl`(`addtime`, `id`, `name`) VALUES ('2016-12-13 20:26:00', 4, '小李'); #start 317 end 487 time 2016-12-13 20:26:26UPDATE `test`.`tbl` SET `addtime`='2016-12-12 00:00:00', `id`=4, `name`='小李' WHERE `addtime`='2016-12-13 20:26:00' AND `id`=4 AND `name`='小李' LIMIT 1; #start 514 end 701 time 2016-12-13 20:27:07DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-10 00:04:33' AND `id`=1 AND `name`='小趙' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-10 00:04:48' AND `id`=2 AND `name`='小錢' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-13 20:25:00' AND `id`=3 AND `name`='小孫' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05DELETE FROM `test`.`tbl` WHERE `addtime`='2016-12-12 00:00:00' AND `id`=4 AND `name`='小李' LIMIT 1; #start 728 end 938 time 2016-12-13 20:28:05 |