資料恢復新姿勢——通過ibd和frm檔案恢復資料

沃趣科技發表於2018-12-12

一、背景

1.1、需求來源

需要給客戶將生產環境的資料恢復到測試環境,但是線上環境的xtrabackup全備資料量太大,拷貝下來比較麻煩,並且需要恢復的資料只有整庫中的兩張表的資料,所以客戶只是將全備中的對應表的ibd檔案以及frm檔案拷貝下來了,要求根據ibd檔案以及frm檔案進行資料恢復。

1.2、環境介紹

資料庫版本:MySQL-5.7.22

資料庫要求:innodb_file_per_table=1


二、解決方案步驟

2.1、準備工作

  • 準備好需要進行資料恢復的表ibd檔案以及frm檔案

  • 安裝一個新的MySQL例項

    • innodb_file_per_table 
      安裝步驟省略

2.2、表結構恢復

在資料庫中建立一張表名與被恢復表表名一致的表,表結構不限制 

將新建表的ibd檔案以及frm檔案拷貝到tmp目錄下備份

# cp message_index.* /tmp/

使用被恢復的frm檔案替換新建立的同名表的frm檔案

# cp /data2/message_index.frm ./
cp:是否覆蓋"./message_index.frm"? y
# chown -R mysql:mysql ./*

在資料庫中執行 show create table 語句 
注意需要在
show create table  檢視錶結構之前執行 flush tables 語句,因為如果message_index表之前被開啟過,那麼表結構會被快取在記憶體中, show create table 不會報錯,也就無法從錯誤日誌中拿到我們需要的資訊。 

檢視error.log,獲取被恢復表的欄位數 
錯誤日誌中會列印我們需要恢復的表的欄位數,這邊可以看到我們需要恢復的表中含有6個欄位 

刪除message_index表,並重新建立message_index表 
從上面的步驟中我們知道被恢復表中含有6個欄位,所以重新建立的message_index表需要含有6個欄位,欄位名以及欄位型別不限制 

再次使用被恢復的frm檔案替換新建立的同名表的frm檔案

# cp /data2/message_index.frm ./
cp:是否覆蓋"./message_index.frm"? y
# chown -R mysql:mysql ./*

在MySQL配置檔案中新增 innodb_force_recovery=6 ,並重啟資料庫 

通過 show create table 語句拿到message_index表的表結構 

至此,我們就拿到了我們需要進行恢復的表的表結構。

2.3、表資料恢復

拿到表結構之後,表資料恢復步驟相對錶結構恢復步驟而言會簡單一些

  • innodb_force_recovery=6 從配置檔案中去掉、使用/tmp目錄下的ibd檔案以及frm檔案覆蓋當前的對應檔案、重啟資料庫

  • 在資料庫中按照獲取到的表結構新建一張message_index表

  • 執行 alter table discard tablespace 語句

mysql> alter table message_index discard tablespace;


將要恢復的表的ibd檔案拷貝到當前庫下,並更改屬主以及屬組

# chown -R mysql:mysql ./*

執行 alter table import tablespace 語句

mysql> alter table message_index import tablespace;


可以看到資料已經都恢復回來了。


三、總結

  • 以上我們通過xtrabackup全備中的ibd檔案以及frm檔案恢復了資料,這樣也就代表著xtrabackup就算備份失敗,只要有部分ibd檔案以及frm檔案保證完好,MySQL也是可以進行資料恢復的,在極端情況下也能儘可能地減少損失。但是由於xtrabackup是通過記錄redo日誌的方式來儲存備份過程中產生的增量資料,這一部分增量資料目前還沒有辦法恢復。

  • 匯入表空間的方式,也給MySQL大資料量遷移方案提供了一種思路:直接拷貝ibd檔案的方式。


| 作者簡介

沈 剛·沃趣科技資料庫技術專家

熟悉MySQL資料庫執行機制,豐富的資料庫及複製架構故障診斷、效能調優、資料庫備份恢復及遷移經驗。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-2284925/,如需轉載,請註明出處,否則將追究法律責任。

相關文章