當 MySQL 未及時備份、遭誤刪或 ibdata 系統表空間損壞時,若仍殘留部分 .frm(表結構)與 .ibd(獨立表空間)文件,仍有機會挽回數據。本文詳細記錄基於 InnoDB 獨立表空間模式(innodb_file_per_table=1)的數據恢復實戰步驟。
my.ini 設定 innodb_file_per_table = 1),否則無法使用此方法。CREATE TABLE `weibo_qq0` (`weiboid` BIGINT(20)) ENGINE=InnoDB DEFAULT CHARSET=utf8;service mysqld stop.frm 文件覆蓋剛建立的同名文件。my.ini,添加 innodb_force_recovery=1(若失效可嘗試 2~6,數值越大恢復模式越激進)。SHOW CREATE TABLE weibo_qq0 即可獲取完整建表 SQL。關鍵原理:InnoDB 內部以「表空間 ID」追蹤數據一致性。恢復時必須讓新表的表空間 ID 與舊 .ibd 文件記錄的 ID 一致。
innodb_force_recovery,重啟 MySQL 進入正常模式。.ibd 與 .frm 分離:ALTER TABLE weibo_qq0 DISCARD TABLESPACE;.ibd 文件複製至新表所在目錄。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。FOR ($i=1; $i<=111; $i++) { CREATE TABLE t$i (id INT) ENGINE=InnoDB; }.ibd,再次導入:ALTER TABLE weibo_qq0 DISCARD TABLESPACE;.ibdALTER TABLE weibo_qq0 IMPORT TABLESPACE;innodb_force_recovery=1(或更高),直到能 SELECT 出數據,隨即 mysqldump 導出。針對大量分表(如 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 導出數據。