MyISAM 表因無事務、索引與數據分離,極易因斷電、殺進程、磁盤故障導致損壞。本文系統梳理損壞成因、典型報錯、預防體系,並對比三種修復路徑:SQL 層 CHECK/REPAIR TABLE、命令列 myisamchk、批量工具 mysqlcheck,助你在故障發生時快速止血。
kill -9、服務器死機、MySQL 進程被 OOM Killer 殺掉 → 數據文件 (.MYD) 與索引文件 (.MYI) 不一致。| 現象 | 典型錯誤信息 |
|---|---|
| 查詢報錯 | Incorrect key file for table '...'. Try to repair it |
| 數據缺失/不全 | Can't find record in '...' 或返回行數少於預期 |
| 表標記崩潰 | Table '...' is marked as crashed and should be repaired |
| 無法打開 | Can't open file: 'xxx.MYI' (errno: 145) |
cron 跑 mysqlcheck -A -c 或 CHECK TABLE。OPTIMIZE TABLE 整理碎片,降低損壞概率。systemctl stop mysqld / mysqladmin shutdown,禁用 kill -9。| 場景 | 推薦工具 | 前置條件 | 優缺點 |
|---|---|---|---|
| MySQL 服務正常運行 | CHECK/REPAIR TABLE | 表可訪問 | 在線操作,加讀/寫鎖,大表耗時長 |
| MySQL 無法啟動/服務掛掉 | myisamchk | 服務完全停止 | 離線操作,速度最快,需手動指定 .MYI 路徑 |
| 批量巡檢/修復所有庫 | mysqlcheck | 服務運行 | 一鍵全庫,支援並行,適合維護窗口 |
-- 1. 進入庫 mysql -uroot -p -D db_name -- 2. 檢查 CHECK TABLE tbl_name; -- Msg_type=Error/Corrupt 需修復 -- 3. 修復 REPAIR TABLE tbl_name; -- 單表 REPAIR TABLE tbl1, tbl2, tbl3; -- 多表 -- 4. 複查 CHECK TABLE tbl_name; -- 期望 Msg_text='OK'
注意:REPAIR TABLE 會重建 .MYI,若 .MYD 也損壞可能丟失數據,建議先備份 cp tbl_name.* /backup/。
# 1. 停止服務 systemctl stop mysqld # 2. 定位數據目錄 cd /var/lib/mysql/db_name # 3. 檢查單表 myisamchk tbl_name.MYI # 4. 修復(-r 恢復模式,-q 快速,-f 強制) myisamchk -r -q tbl_name.MYI # 快速恢復(推薦首選) myisamchk -r -f tbl_name.MYI # 強制恢復(快速失敗時) # 5. 批量修復整個庫 myisamchk -r -q *.MYI
啟動腳本掛載:在 /etc/rc.local 或 systemd 啟動前掛載:
[ -S /var/lib/mysql/mysql.sock ] || myisamchk -r -q /var/lib/mysql/*/*.MYI
確保 MySQL 未啟動時自動修復。
# 檢查並修復所有庫所有表 mysqlcheck -A -c -r -u root -p # 僅修復(跳過檢查) mysqlcheck -A -r -u root -p # 併行加速(MySQL 5.6+) mysqlcheck -A -r --parallel=4 -u root -p
CHECK TABLE tbl_name 返回 OK。SELECT COUNT(*) FROM tbl_name 與業務預期一致。EXPLAIN 走預期索引。crashed/corrupt 關鍵字。MyISAM 損壞不可怕,可怕的是「無預案、無備份、無演練」。建立「日巡檢、周優化、月演練」機制,才是根治之道。