MySQL 崩潰後僅遺留 .frm 表定義檔(InnoDB 資料與索引在共享表空間 ibdata1),無法直接讀取。本文實測驗證一套「建同名表→停服→覆蓋 .frm→啟服」四步法,成功從 .frm 還原表結構,為誤刪表、檔案系統損壞場景提供最後防線。
.frm 儲存表結構元資料(欄位、索引、引擎、字元集等),二進制格式不可直接編輯。ibdata1 或 .ibd(獨立表空間),.frm 僅是「入口地圖」。mysql> CREATE DATABASE recovery_db;
mysql> USE recovery_db;
mysql> CREATE TABLE test_innodb (id BIGINT NOT NULL) ENGINE=InnoDB;
-- 此時產生 recovery_db/test_innodb.frm
systemctl stop mysqld
# 或
service mysql stop
cp /backup/path/test_innodb.frm /var/lib/mysql/recovery_db/test_innodb.frm
# 確保檔案擁有者 mysql:mysql、權限 660
systemctl start mysqld
mysql> USE recovery_db;
mysql> DESC test_innodb;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| A | int(11) | YES | | NULL | |
| B | varchar(30) | YES | | NULL | |
| C | date | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
✅ 結構完美還原:原表三欄位 A/B/C 全數恢復,證明 .frm 獨立攜帶完整定義。
| 場景 | 可行性 | 說明 |
|---|---|---|
| 誤執行 DROP TABLE | ✅ 結構可恢復 | .frm 未被刪除(極少見),或從檔案系統層恢復 .frm |
| 誤執行 ALTER TABLE 導致結構錯誤 | ✅ 結構可恢復 | 用備份 .frm 覆蓋 |
| 資料頁損壞但 .frm 完好 | ✅ 結構可恢復 | 資料需配合 innodb_force_recovery 或 Percona Data Recovery Tool |
| 僅有 .frm 無 ibdata1/.ibd | ⚠ 僅結構 | 資料無法恢復,需配合備份/備份+binlog |
| MySQL 版本不匹配(5.6 .frm 用於 8.0) | ❌ 不可行 | .frm 格式跨大版本不兼容 |
innodb_file_per_table=ON,每表獨立 .ibd,便於單表備份/遷移/恢復。mysqldump -d --single-transaction --routines --triggers --events db > structure.sql。