MySQL 表損壞是 DBA 必修課。本文系統梳理成因、癥狀、預防與分級修復流程,涵蓋 MyISAM 與 InnoDB 兩大引擎。
mysqld 寫入時被 kill -9 強制終止myisamchk 與 mysqld 同時操作同一表OOM Killer 殺進程Incorrect key file for table: '...'. Try to repair itTable 'p' is marked as crashed and should be repairedCan't open file: 'xxx.MYI' (errno: 145)ERROR 1034 (HY000): Incorrect key fileCHECK TABLE(無需停服務)或 myisamchk(需停服務)OPTIMIZE TABLE 整理碎片mysqld,禁用 kill -9innodb_tablespace_monitor 檢查表空間完整性myisamchk *.MYI # 快速檢查
myisamchk -e *.MYI # 延伸檢查
myisamchk -s *.MYI # 靜默模式
# 僅修復報錯的表
myisamchk -r -q tbl_name # 快速恢復模式(僅重建索引)
# 失敗則
myisamchk -r tbl_name # 恢復模式(刪除錯誤記錄、重建索引)
# 仍失敗則
myisamchk --safe-recover tbl_name # 安全恢復(舊演算法,較慢但穩)
修復前務必備份 .MYD、.MYI。
.MYD 到安全處.frm 重建空表:
mysql db_name
SET AUTOCOMMIT=1;
TRUNCATE TABLE tbl_name; -- 或 DELETE FROM tbl_name
quit.MYD 複製回新建的資料檔myisamchk -r -q或一鍵:REPAIR TABLE tbl_name USE_FRM;
.frm → 回階段 3.MYI → 回階段 2CREATE TABLE:在別庫建同結構表,複製 .frm/.MYI 回來 → 階段 2/3InnoDB 具備崩潰恢復能力,若資料頁損壞:
SELECT * INTO OUTFILE 導出完好資料my.cnf 加入 innodb_force_recovery = 1..6 強制啟動導出:| 值 | 常數 | 行為 |
|---|---|---|
| 1 | SRV_FORCE_IGNORE_CORRUPT | 忽略損壞頁,嘗試 SELECT 跳過 |
| 2 | SRV_FORCE_NO_BACKGROUND | 阻止主執行緒(清除操作) |
| 3 | SRV_FORCE_NO_TRX_UNDO | 不執行事務回滾 |
| 4 | SRV_FORCE_NO_IBUF_MERGE | 阻止插入緩衝合併、不計算統計 |
| 5 | SRV_FORCE_NO_UNDO_LOG_SCAN | 視未完成事務為已提交 |
| 6 | SRV_FORCE_NO_LOG_REDO | 不做 Redo Log 前滾 |
≥4 可導出多數資料,=6 風險最高。>0 時 InnoDB 禁止 INSERT/UPDATE/DELETE。DROP/CREATE TABLE 移除壞表停止失控回滾。表損壞不可怕,可怕的是「無備份、不演練」。建立「日檢、周優、月備、季演練」機制,才是根治之道。