利用 MySQL bin log 恢復資料表

2021-06-27 08:44:27 字數 1951 閱讀 1526



今天公司一同事使用典型的「update 不帶 where 語句」誤操作把資料庫中一張極重要資料表 player 給「做掉了」,還算幸運的是該資料庫每3個月會完整備份一次,最近一次的備份點為6月30日,再加上 bin-log 保留了30天的資料,可以根據這兩份資料還原資料表的內容。方法看上去非常簡單清晰,但是具體執行起來還是遇到了很多問題,下面整理了一些關鍵問題,以備以後災難再發生時可供參考。

/data

/mysql

/bin

/mysqlbinlog mysql-bin

.001468

>

mysql-bin

.001468

.txt

由於一開始我們想當然認為針對 player 表的更新 sql 都是單行語句,所以就直接使用 grep 進行行級的提取,這種簡單做法也為我們後面的恢復失敗埋下了「地雷」。

先看一下文字格式 bin-log 的記錄格式:

#at 

7473

#11063011:

56:05server id 

1end_log_pos 

7612

query   thread_id=6

exec_time=0

error_code=0

settimestamp

=1309406165

/*!*

/;update ssmatch

.young_league_match_7 

setstatus

='playing' where mid

=699617

/*!*/;

顯而易見,正確的提取方法應該是:

1. 讀取一行資料,如果行首字元為'#'則跳過,否則執行第2步;

2. 檢測行尾字元是否為';',如果不是則繼續讀下一行直到行尾字元為';',所有讀取的行構成一條 sql 語句,執行第3步;

3. 清空讀取的行快取,如果已到檔案尾則結束,否則跳到第1步迴圈處理;

下面是實際提取player表更新sql語句的命令:

cat mysql-bin

.001468

.txt | grep -i \"

player\" |grep -v \"player_position\|player_league\|young\|match_info\|tactics\|player_buddy\|player_champion\|player_cup\|player_friend\|staff\|match_report\|setpieces_nid\|old_player_ca\|new_player_ca\" > mysql-bin.001468.player

最後說一下上面提到的「地雷」問題,我們在資料重跑進度達到80%的時候遇到 bin-log 中下面格式的update語句:

update

player 

set/*

此粗省略更新字段內容 ... 

*/where

nid 

=1111

「它換行了!!!where語句在第2行!!!」,悲催啊,上面的行級提取方法將完整的update語句截斷了,重跑執行的是「不帶 where 的 update」!!!一下回到解放前,這下只能重頭開始再執行一遍!在重跑前還需要將這種「病毒」語句清理掉。

所以,除非你非常肯定確定一定不會出現多行sql語句,否則都一定要使用上面的正確做法提取sql。

一條寶貴的經驗:在恢復資料的過程中一定要做階段備份,比如在重跑 sql 時發生錯誤導致中斷,那麼可以先把該時間點的資料表複製乙份,然後再從中斷點往後繼續執行;更好的做法是一開始就按階段進行資料恢復,比如有30個 bin-log 檔案需要重跑,那麼可以每跑5~10個 bin-log 後做一次備份;這樣的好處是一旦發生「意外」就可以從上乙個備份點開始執行,而不是重頭執行。請記住在恢復資料的過程中你永遠無法預知接下會發生什麼事故!

利用mysqlbinlog工具恢復MySQL資料庫

如果mysql伺服器啟用了二進位制日誌,你可以使用mysqlbinlog工具來恢復從指定的時間點開始 例如,從你最後一次備份 直到現在或另乙個指定的時間點的資料。關於啟用二進位制日誌的資訊,參見5.11.3節,二進位制日誌 對於 mysqlbinlog的詳細資訊,參見mysql手冊8.6節,mysq...

利用 MySQL bin log 恢復資料表

今天公司一同事使用典型的 update 不帶 where 語句 誤操作把資料庫中一張極重要資料表 player 給 做掉了 還算幸運的是該資料庫每3個月會完整備份一次,最近一次的備份點為6月30日,再加上 bin log 保留了30天的資料,可以根據這兩份資料還原資料表的內容。方法看上去非常簡單清晰...

mysql資料恢復 mysqlbinlog

恢復資料的關鍵是資料庫開啟了log bin window下my.ini裡 log bin mysql bin 日誌檔案的字首,可修改,如 mysql bin.000001 然後預設放在資料庫根目錄的data資料夾裡 如果誤刪了資料庫,可以用之前備份的資料庫 如2014 05 12 doc命令列下用m...