MYSQL专题-使用Binlog日志恢复MySQL数据
大家有沒有碰到過由于誤操作把測試數據庫的一張表給刪除了,導致測試的數據都被刪除了,然后手足無措,測試把你一定數落,頓時感覺自己要死了?今天就教你即使誤刪了也可以將刪除的數據恢復,以后誤刪再也不用驚嚇了。當然,實際操作中最好還是認真對待,小心操作。還有就是在大公司內,數據也不是你想刪就能刪掉的,有無數權限/備份阻攔著你,所以通常情況下你都不會有機會,但還是備著以防萬一。
Binlog簡述
MySql數據恢復主要依賴的是Binlog日志,在之前的文章中MYSQL專題-MySQL三大日志binlog、redo log和undo log也有講過,大家有興趣可以去看看,這里簡單介紹一下:
- binlog是記錄所有數據庫表結構變更(例如CREATE、ALTER TABLE…)以及表數據修改(INSERT、UPDATE、DELETE…)的二進制日志;
- binlog不會記錄SELECT和SHOW這類操作,因為這類操作對數據本身并沒有修改,但你可以通過查詢通用日志來查看MySQL執行過的所有語句。
通過Binlog日志,我們解決以下的問題:
- 恢復數據:(今天要說的重點);
- 數據庫復制:主從數據庫是通過將binlog傳給從庫,從庫有兩個線程,一個I/O線程,一個SQL線程,I/O線程讀取主庫傳過來的binlog內容并寫入到relay log,SQL線程從relay log里面讀取內容,寫入從庫的數據庫;
- 審計:用戶可以通過二進制日志中的信息來進行審計,判斷是否有對數據庫進行注入攻擊。
所以說,想要能夠恢復數據,首先你得打開Mysql的binlog,在平常你自己安裝的單機Mysql中,默認情況下不會開啟。下面就一步步地實踐下如何開啟你服務器上的Binlog日志。
Binlog開啟(Windows示范)
首先進入數據庫控制臺,運行指令:
可以看到我們的binlog是開啟的(MySql8.0.21默認是開啟的狀態,8.0以后都是默認開啟,加了反而會報錯),如果你的是低版本的沒有開啟,輸入 net stop mysql停止MySql,修改mysql的配置文件my.ini。添加如下配置:
輸入 net start mysql重啟mysql服務,然后再執行show variables like 'log_bin’就可以看到已經開啟了,執行 show binary logs,發現有對應的binlog日志:
當然你也可以到對應的Mysql安裝目錄的data中進行查看:
如果想關閉binlog日志,低版本的直接去掉就行,自動默認的加入skip-log-bin,然后重啟即可。需要說明的是,每當我們重啟MySQL一次,會自動生成一個binlog文件。我們也可以手動的來刷新binlog文件,通過 flush logs,同樣會新創建一個binlog文件。實際上當服務器在重啟時,也會調用flush logs操作。
Binlog實操
首先新建數據庫binLogTest,新建一張表tableLog1,SQL代碼如下:
CREATE DATABASE `binLogTest` ; USE `binLogTest`; DROP TABLE IF EXISTS `tableLog1`; CREATE TABLE `tableLog1` (`id` int(11) DEFAULT NULL,`name` varchar(20) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;然后插入兩條數據,分別是 (1,‘tom’),(2,‘jack’)
INSERT INTO `tableLog1` VALUES (1,'tom'),(2,'jack');執行完成以后,我們再控制臺使用show master status看以下binlog日志的狀態:
可以看到,現在我們正在使用 binlog.0000004 ,并且這個文件現在正在記錄到1207行。
然后,使用flush logs來主動刷新一次binlog,然后再次查看狀態:
可以看到,現在日志文件在 binlog.000005 文件中,位置為156。也就是我們主動刷新了一次binlog,生成了新的binlog.000005,而binlog.000004則已經歸檔了,不會再寫入新的日志進去了。
接下來我們再插入兩條數據:
可以看到我們已經成功插入了4條數據:
我們再次flush logs,把binlog.000005日志存檔,開啟新的binlog.000006日志,這樣,每次我們插入的數據彼此獨立。實際情況下,binlog會比較復雜,這里也是做了簡化,為了理解更方便。
然后我們刪除id為4的數據,并且再次刷新binlog,如此一來,binlog.000006里面只有一條刪除操作:
我們來好好觀察下binlog.00005和binlog.00006兩個binlog,使用命令:show binlog events in 'binlog.000005’和show binlog events in ‘binlog.000006’:
一條插入操作的完整日志如上面標注所示。我們的目的是恢復誤刪的數據,其實就是將binlog.000005日志的插入記錄重演一遍,而不需要理會binlog.000006的操作(因為刪除是一個誤操作)。在實際的線上環境中,我們肯定需要將binlog導出后,仔細篩選出誤操作,并將其排除,之后再運行binlog,這里為了方便演示直接進行。我們只做一個恢復兩條插入語句的操作。
首先看到我們的數據庫中的確是不存在id為4的記錄。
然后我們執行以下語句:
需要說明的是,這里的語句執行不要在Mysql中執行,否則會報錯:
應該在binlog所在地方再開一個執行窗口執行:
執行完成以后我們在看一下數據:
看到的確是恢復了數據,為什么會有兩條id為3的數據,是因為我們執行的文件是插入id為3和4的binlog,大家可以依據自己數據的情況進行恢復,只要配置不同的起始位置即可:
還有一點需要說明的,在最開始執行語句沒有加入–no-defaults,導致出錯:
大家加入即可。
看完binlog日志恢復數據的原理,希望大家以后在定期備份數據庫的腳本里,也能夠加上刷新binlog日志的命令,這樣一旦某天丟失數據,可以將當天binlog數據單獨拿出來還原,做到清晰可辨,也加快恢復效率。
猜你感興趣:
MYSQL專題-絕對實用的MYSQL優化總結
MYSQL專題-MySQL事務實現原理
MYSQL專題-MVCC多版本并發控制
MYSQL專題-MySQL三大日志binlog、redo log和undo log
更多文章請點擊:更多…
總結
以上是生活随笔為你收集整理的MYSQL专题-使用Binlog日志恢复MySQL数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 教你用BitMap排序、查找和存储大量数
- 下一篇: 教你从0到1搭建秒杀系统-防超卖