首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

利用 frm 與 ibd 文件恢復 MySQL ibdata 損壞或遺失數據

     編輯:MySQL 綜合教學

利用 frm 與 ibd 文件恢復 MySQL ibdata 損壞或遺失數據

當 MySQL 未及時備份、遭誤刪或 ibdata 系統表空間損壞時,若仍殘留部分 .frm(表結構)與 .ibd(獨立表空間)文件,仍有機會挽回數據。本文詳細記錄基於 InnoDB 獨立表空間模式(innodb_file_per_table=1)的數據恢復實戰步驟。

前置條件與注意事項

  1. 僅適用於 InnoDB 存儲引擎。MyISAM 只需直接複製數據文件即可。
  2. 生產環境必須已啟用獨立表空間(my.ini 設定 innodb_file_per_table = 1),否則無法使用此方法。

第一階段:恢復表結構(.frm 文件)

  1. 建立一個全新、空的數據庫(無任何表與操作)。
  2. 在該庫中建立一個同名表,結構任意,但必須指定 ENGINE=InnoDB。例如:
    CREATE TABLE `weibo_qq0` (`weiboid` BIGINT(20)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  3. 停止 MySQL 服務:service mysqld stop
  4. 用備份的 .frm 文件覆蓋剛建立的同名文件。
  5. 修改 my.ini,添加 innodb_force_recovery=1(若失效可嘗試 2~6,數值越大恢復模式越激進)。
  6. 啟動 MySQL,執行 SHOW CREATE TABLE weibo_qq0 即可獲取完整建表 SQL。

第二階段:恢復表數據(.ibd 文件)

關鍵原理:InnoDB 內部以「表空間 ID」追蹤數據一致性。恢復時必須讓新表的表空間 ID 與舊 .ibd 文件記錄的 ID 一致。

  1. 註釋掉 innodb_force_recovery,重啟 MySQL 進入正常模式。
  2. 按第一階段導出的 SQL 重建表結構。
  3. 丟棄表空間,使新建表的 .ibd 與 .frm 分離:
    ALTER TABLE weibo_qq0 DISCARD TABLESPACE;
  4. 將備份的舊 .ibd 文件複製至新表所在目錄。
  5. 嘗試導入表空間(預期會報錯):
    ALTER TABLE weibo_qq0 IMPORT TABLESPACE;
    錯誤日誌會顯示類似:tablespace id in file '.testweibo_qq0.ibd' is 112, but in the InnoDB data dictionary it is 1。舊表 ID=112,新表 ID=1。
  6. 製造 111 個臨時表 將當前表空間 ID 從 1 遞增至 112(因建表已佔用 1):
    FOR ($i=1; $i<=111; $i++) { CREATE TABLE t$i (id INT) ENGINE=InnoDB; }
  7. 再次丟棄目標表空間,複製舊 .ibd,再次導入:
    ALTER TABLE weibo_qq0 DISCARD TABLESPACE;
    複製 .ibd
    ALTER TABLE weibo_qq0 IMPORT TABLESPACE;
    此次應無錯誤,但查詢仍可能無結果。
  8. 重新啟用 innodb_force_recovery=1(或更高),直到能 SELECT 出數據,隨即 mysqldump 導出。
  9. 在全新數據庫中導入導出的 SQL,完成數據重建。

擴展:分表場景的批量自動化

針對大量分表(如 inv_crawl_weibo_qq_0 ~ 111),可編寫 Shell 腳本循環執行上述步驟:

# 1. 批量建表
for i in `seq 0 111`; do
  mysql -uroot -P33061 -h127.0.0.1 -Dtestdd -e "CREATE TABLE inv_crawl_weibo_qq$i (id BIGINT(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)) ENGINE=InnoDB;"
done

# 2. 批量丟棄表空間
for i in `seq 0 111`; do
  mysql -uroot -P33061 -h127.0.0.1 -Dtestdd -e "ALTER TABLE inv_crawl_weibo_qq$i DISCARD TABLESPACE;"
done

# 3. 複製備份的 .ibd 文件至數據目錄(注意文件權限)

# 4. 批量導入表空間
for i in `seq 0 111`; do
  mysql -uroot -P33061 -h127.0.0.1 -Dtestdd -e "ALTER TABLE inv_crawl_weibo_qq$i IMPORT TABLESPACE;"
done

無報錯即表示導入成功。最後同樣開啟 innodb_force_recovery 導出數據。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved