repair table报错“storage engine doesn’t support repair”是因为该命令仅支持myisam引擎,innodb执行必报error 1031;必须先用show create table或information_schema确认引擎为myisam才能使用,mysql 8.0+系统表如mysql.user已默认为innodb,旧经验不可套用。

REPAIR TABLE报错“storage engine doesn’t support repair”
这不是表坏了,是引擎选错了。InnoDB 表执行 REPAIR TABLE 必然失败,错误信息就是 ERROR 1031 (HY000): Table storage engine for 'xxx' doesn't support repair。MySQL 8.0+ 默认引擎是 InnoDB,看到 “Table is marked as crashed” 就跑 REPAIR TABLE,十有八九直接撞墙。
必须先确认引擎:
-
SHOW CREATE TABLE xxx;—— 看输出里有没有ENGINE=MyISAM -
SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'xxx';—— 返回值必须是MyISAM才能继续
特别注意:mysql.user 这类系统表在 5.7 是 MyISAM,8.0+ 已切 InnoDB,旧经验套用必错。
CHECK TABLE返回OK却仍不能查数据
CHECK TABLE 返回 status = OK 只说明当前文件结构没被 MySQL 拒绝,不代表索引可用或数据逻辑正确。常见假阳性场景:
- 缓存未刷新,
SHOW TABLE STATUS里Comment还写着crashed,但CHECK TABLE暂时没报错 - .MYI 文件头部校验通过,但深层索引节点已错位,查询时才暴露
Incorrect key file for table - 修复后没执行
ANALYZE TABLE,优化器还在用旧的统计信息,EXPLAIN显示key为空、rows高得离谱
验证是否真修好:对主键或唯一索引字段跑 SELECT COUNT(*) 和 SELECT COUNT(DISTINCT key_col),结果不一致就说明索引重建漏行或跳过了冲突。
REPAIR TABLE执行中断或静默失败
MyISAM 修复过程不可逆,但失败不一定报错,可能卡住、超时退出或写一半就停——尤其当磁盘或权限出问题时:
-
tmpdir空间不足:EXTENDED 模式会生成xxx.TMD临时文件,要求空闲空间 ≥ 原.MYI大小的 2 倍;查路径用SELECT @@tmpdir; - 文件权限不对:数据库目录下
xxx.MYD、xxx.MYI、xxx.frm三文件属主必须是mysql用户,否则中途静默失败 -
.frm文件损坏或跨版本:用vim或cat碰过.frm,或把 5.7 的.frm直接扔进 8.0 实例,会触发ERROR 1033 (HY000): Incorrect information in file,REPAIR TABLE根本不会启动
修复后查询变慢或索引失效
命令返回 OK 不等于业务恢复。MyISAM 修复不自动更新统计信息,也不校验索引语义(比如前缀索引长度、全文索引分词规则),容易出现“能查,但全表扫”的静默退化:
- 必须立刻执行
ANALYZE TABLE xxx;,否则优化器继续按旧Cardinality估算 - 对关键查询跑
EXPLAIN SELECT ...,确认key列显示预期索引名,且rows值明显下降(比如从百万级降到几百) - 如果用了
USE_FRM模式,所有二级索引都得重新评估——它只按.frm定义重建结构,不保证原有索引逻辑(如KEY idx(a(10))可能被当成a全字段索引)
真正麻烦的是 .MYD 文件已有物理坏块,REPAIR TABLE EXTENDED 会把坏数据也复制进去,表面修复成功,实际埋了脏数据。这种情况下,myisamchk --safe-recover 离线抢救比 SQL 层修复更底层、更可靠。











