修改mysql數(shù)據(jù)時(shí)兄世,有時(shí)候因?yàn)橥藢?xiě)where語(yǔ)句或是條件不對(duì),造成數(shù)據(jù)被錯(cuò)誤的刪除或更新啊研,以前使用oracle的時(shí)候御滩,有個(gè)閃回的工具,可以在一定時(shí)間內(nèi)通過(guò)時(shí)間點(diǎn)來(lái)查詢(xún)表的歷史數(shù)據(jù)党远,很好用削解。但mysql好像沒(méi)有這個(gè)功能,一旦提交的修改沟娱,就只能通過(guò)log來(lái)手動(dòng)找回?cái)?shù)據(jù)氛驮,不過(guò)這個(gè)功能還是很好用的
這個(gè)功能依賴(lài)的是mysql的binlog 功能,binlog會(huì)把數(shù)據(jù)庫(kù)的幾乎所有操作(主要是對(duì)數(shù)據(jù)的修改操作)記錄到一個(gè)二進(jìn)制文件里济似,這個(gè)功能在最近的mysql版本里都是默認(rèn)打開(kāi)的矫废,雖然binlog會(huì)給數(shù)據(jù)庫(kù)的性能增加些許的負(fù)擔(dān)盏缤,但是相比帶來(lái)的便利,這點(diǎn)性能負(fù)擔(dān)顯得微不足道蓖扑,使用binlog的好處有兩點(diǎn)唉铜,一是可以讀取這個(gè)log文件來(lái)查找對(duì)數(shù)據(jù)庫(kù)的修改記錄,另一個(gè)就是用于數(shù)據(jù)庫(kù)主從復(fù)制律杠。下面就來(lái)利用binlog找回被誤更新的數(shù)據(jù)
整個(gè)恢復(fù)過(guò)程大概分5步:
- 檢查mysql的binlog 設(shè)置
show variables like 'log_bin'; # 檢查是否開(kāi)啟了binlog潭流,
On # 表示已經(jīng)開(kāi)啟binlog
show global variables like "%binlog_form%"; # 檢查binlog的格式
ROW # 如果為row,表示數(shù)據(jù)庫(kù)會(huì)記錄每一行數(shù)據(jù)的修改
關(guān)于binlog的格式柜去,主要有兩種灰嫉,一種是基于sql的,就是會(huì)記錄執(zhí)行過(guò)的每條sql語(yǔ)句诡蜓,另一種就是上面這種基于row 行數(shù)據(jù)的熬甫,這種格式的log非常詳細(xì),會(huì)記錄每一行數(shù)據(jù)修改前和修改后的記錄蔓罚,適合對(duì)誤操作進(jìn)行恢復(fù)
-
定位時(shí)間范圍和binlog
因?yàn)閞ow 格式的binlog文件特別大,人很難看的過(guò)來(lái)瞻颂,為了縮小查找范圍豺谈,最好預(yù)估一下誤操作的時(shí)間范圍,比如十分鐘前贡这,昨天下午兩點(diǎn)到三點(diǎn)茬末,這種時(shí)間范圍都可以。與此同時(shí)盖矫,mysql的binlog文件也會(huì)有很多丽惭,可以通過(guò)show binary logs; 來(lái)查看binlog文件列表,
image.png
然后預(yù)估一下發(fā)生誤操作的時(shí)候使用的是哪個(gè)binlog辈双,預(yù)估錯(cuò)了也沒(méi)關(guān)系责掏,后面可以挨個(gè)檢查binlog文件。
導(dǎo)出log
有了上面的時(shí)間范圍和預(yù)估的binlog文件湃望,那就好辦了换衬,因?yàn)閎inlog是二進(jìn)制文件,沒(méi)法人工查看证芭,所以mysql提供了mysqlbinlog 工具來(lái)把二進(jìn)制轉(zhuǎn)成文本文件來(lái)查看瞳浦,可以使用下面的命令:
mysqlbinlog --no-defaults --start-datetime='2020-07-13 22:10:13' --stop-datetime='2020-07-13 22:10:33' -v binlog.000329 > /home/yuxy/bak.txt
上面語(yǔ)句里預(yù)估發(fā)生的時(shí)間在 22:10:13秒到22:10:33之間,log寫(xiě)在在binlog.000329里废士, -v 表示把binlog里編碼過(guò)的sql語(yǔ)句解碼成字符串叫潦,沒(méi)有這個(gè)參數(shù)的話,看到的log里的sql語(yǔ)句都是base64 格式的官硝。最后把上面的結(jié)果輸出到bak.txt文件里矗蕊。
那這個(gè)binlog文件里log到底是什么樣子的呢四敞? 如下:
我更新的時(shí)候忘了寫(xiě)where過(guò)濾,造成把全表都更新了拔妥,但log里為每一條行數(shù)據(jù)記錄了一個(gè)update語(yǔ)句忿危,并且圖中紅框里記錄了修改之前的值,綠框里記錄了修改之后的值没龙,這樣修改前后的數(shù)據(jù)一目了然铺厨,找回原來(lái)的數(shù)據(jù)也就很簡(jiǎn)單了