myisam表损坏需先通过错误日志“marked as crashed”或show table status中comment含crashed确认,再用repair table(轻度)、extended(中度)或myisamchk --safe-recover(重度)修复,完成后必须执行analyze table更新统计信息。

能试,但成功率取决于损坏程度和操作是否及时——MyISAM 没有崩溃恢复机制,所有修复都是“抢救式”的,且不支持回滚。
怎么快速确认是 MyISAM 表损坏?
别猜,直接看错误日志或 SQL 报错:
- 错误日志里出现
Table 'db.table_name' is marked as crashed或Incorrect key file→ 基本锁定 MyISAM - 执行
SHOW TABLE STATUS LIKE 'table_name',观察Comment列是否含crashed字样 - 查引擎:
Engine字段必须是MyISAM;对应磁盘文件是.MYD(数据)、.MYI(索引)、.FRM(结构)
REPAIR TABLE 为什么经常失败?三种模式怎么选
REPAIR TABLE 是在线命令,但底层逻辑很“脆”:它只在 MySQL 进程内运行,无法绕过已损坏的索引头或校验块。常见失败报错如 Repair with keycache failed 或 Key block size is wrong,说明 .MYI 已发生字节级损坏。
-
REPAIR TABLE table_name;:等价于QUICK模式,只重建索引,不读数据 —— 快但只对轻度索引损坏有效 -
REPAIR TABLE table_name EXTENDED;:逐行读取.MYD并重建整个.MYD + .MYI—— 能修多数问题,但要求磁盘剩余空间 ≥ 表大小的 2 倍,否则中途失败且可能残留损坏碎片 -
REPAIR TABLE table_name USE_FRM;:仅当.MYI完全不可解析时才用,它忽略原索引,按.FRM重建空索引 —— 数据还在,但所有索引失效,后续必须立刻执行ANALYZE TABLE
myisamchk 离线修复必须做这三件事
一旦 REPAIR TABLE EXTENDED 返回 Operation failed,就得切到 myisamchk。它直接操作文件,跳过 SQL 层,但风险更高。
- 先停服务:
systemctl stop mysqld(不是restart,必须确保进程完全退出) - 确认路径:
SELECT @@datadir;,然后 cd 到对应数据库子目录,定位table_name.MYI - 首选命令:
myisamchk --safe-recover --force /var/lib/mysql/dbname/table_name.MYI。--safe-recover会尝试从.MYD中提取可读行,比-r更保守;--force防止遇到校验错误就中断 - 若仍失败,再试更激进的:
myisamchk -r -v /path/to/table_name.MYI(-r强制重建,-v显示过程便于判断卡在哪)
修复后必须立即执行 ANALYZE TABLE
无论用哪种方式修完,MySQL 的统计信息(如索引基数、行数估算)都已过期。不更新会导致查询计划严重失准,比如该走索引却全表扫描。这不是可选项,是必做动作。
另外,myisamchk 修复后的文件权限可能不对(尤其跨用户拷贝过),启动前务必检查:ls -l table_name.*,确保属主是 mysql:mysql。修复过程不写 binlog,所以别指望靠 binlog 回放补操作 —— MyISAM 本身就不记事务日志。











