使用MySQL自身複製來恢復binlog

orczhou發表於2016-03-28

在MySQL手冊中一直是推薦使用mysqlbinlog工具來實現指定時間點的資料恢復,事實上,這是一個經常”讓人鬱悶”的辦法。更好的辦法是,使用MySQL內部複製執行緒中的SQL Thread來做恢復。

這個idea來自Lazydba同學;在Google稍作搜尋,在Xaprb上Baron Schwartz也很早提到了使用類似的方法來恢復binlog,在那篇討論中,還可以看到Jeremy Cole也提到:使用MySQL手冊中推薦的方法是困難重重的,而且mysqlbinlog這個辦法從邏輯上來說也是一個錯誤–因為這樣MySQL不得不在兩個不同的地方實現一套相同的邏輯,最終難免會出錯。使用mysqlbinlog來恢復,你可能會需要以下“讓人鬱悶”的問題:

(*) Max_allowed_packet問題
(*) 惱人的Blob/Binary/text欄位問題
(*) 特殊字元的轉義問題
(*) 沒有"斷點恢復":執行出錯後,沒有足夠的報錯,也很難從失敗的地方繼續恢復

1. 如何操作

本文不打算寫一個step by step的文件,只介紹主要的思路和粗略的操作步驟。

1.1 將binlog作為relay log來執行

優點:實施簡單;缺點:需要關閉一次資料庫(不確定不關閉資料庫行不行);

思路:直接將要恢復的binlog拷貝到relay log目錄,並修改slave-info相關的檔案,讓MySQL把binlog當做relay log來執行

簡單的操作步驟:

* 關閉當前例項
* 將binlog拷貝到對應的relay log目錄(datadir或者relay-log引數指定的目錄)
* 開啟relay-log-info-file引數指定的relay-log.info檔案(預設是datadir目錄下的relay-log.info檔案),修改檔案前面兩行。
這兩行的意義分別是:當前執行的relay log檔案;當前執行到relay log檔案的位置(position)
* 開啟relay-log-index檔案(由引數--relay-log-index,預設是資料目錄下的host_name-relay-bin.index)將需要恢復的binlog檔案全路徑列表存在該檔案中
* 啟動資料庫,並start slave io_thread

1.2 從專門構建的binlog server上拉binlog

這個方法,無需啟動資料庫,但是需要重新啟動一個全新的例項,將binlog拷貝到該例項中,這裡稱這個例項為binlog server。然後把需要恢復的例項複製指向這個binlog server。這裡需要做的是,將日誌拷貝到binlog server對應目錄下,並修改對應的master-info檔案,使得備庫能夠dump到這些binlog檔案。

2. 其他需要注意的事項

* 配置檔案中建議加上skip-slave-start,以免在不需要時候slave執行緒自己開始執行了

* start slave的時候,可以通過start slave until的方式,控制slave執行到的位點

* slave執行的其實位點,則通過relay-log.info或者change master to來指定

Good Luck.


相關文章