myisam表索引损坏应优先用repair table,innodb则依赖自动崩溃恢复;myisam修复需据check table结果选quick、extended或use_frm模式,修复后须analyze table并验证查询。

不能直接用 REPAIR TABLE 处理所有“恢复后索引损坏”的场景——它只对 MyISAM 表有效,InnoDB 表执行会报错 Storage engine for the table doesn't support repair,且即使成功返回 OK,也不代表索引真能正常工作。
MyISAM 表恢复后报 Incorrect key file for table 怎么办
这是典型的 .MYI 文件损坏信号,REPAIR TABLE 是首选,但必须配合 CHECK TABLE 判断损坏程度:
- 先运行
CHECK TABLE tbl_name:若返回status = OK,不用修;若提示record delete-link chain broken或error,再动手 -
REPAIR TABLE tbl_name默认是 QUICK 模式,只重建索引树,快但不校验数据行——适合索引断裂但数据完好的情况 - 如果
CHECK TABLE明确报数据逻辑异常(如 “data record is corrupted”),必须加EXTENDED:REPAIR TABLE tbl_name EXTENDED,它会逐行扫描 .MYD 并重建索引,但锁表时间长、IO 压力大 - 修复失败常见原因是
tmpdir空间不足(修复生成临时文件tbl_name.TMD),查SELECT @@tmpdir,确保空闲空间 ≥ 原索引文件大小的 2 倍
InnoDB 表恢复后索引不生效(EXPLAIN 不走索引)怎么办
这不是“索引损坏”,而是元数据与 B+ 树结构脱节,REPAIR TABLE 完全无效,必须重建表并更新统计信息:
- 优先确认索引是否真实存在且可用:
SHOW INDEX FROM tbl_name,重点看Cardinality是否非零;若为NULL或0,说明优化器已放弃该索引 - 用
ALTER TABLE tbl_name ENGINE=InnoDB触发隐式重建——但对严重不一致的表,更可靠的是ALTER TABLE tbl_name FORCE,它强制全量重刷聚簇索引和所有二级索引 - 重建后必须立刻执行
ANALYZE TABLE tbl_name,否则优化器仍沿用旧统计信息,可能继续走全表扫描 - 若恢复是通过物理拷贝
.ibd文件完成的,务必确认innodb_file_per_table=ON且表未被DISCARD TABLESPACE过,否则 MySQL 无法加载索引页
修复后怎么验证索引真的修好了
命令返回 OK 只代表语法执行成功,不代表业务可用。最容易被忽略的是“修复成功但查询变慢数倍”的静默失效:
- 对含
UNIQUE索引的表,立即查重复:SELECT key_col, COUNT(*) FROM tbl_name GROUP BY key_col HAVING COUNT(*) > 1,防止修复过程跳过冲突行 - 用
EXPLAIN SELECT ...检查key列是否命中预期索引名,rows值是否明显下降(比如从 100 万降到几百) - 若表有全文索引或前缀索引,
REPAIR TABLE和ALTER TABLE ... FORCE都不会自动重建它们,需手动ALTER TABLE ... DROP INDEX ... ADD FULLTEXT INDEX ... - MyISAM 的 .MYI 不存数据校验和,修复后无法自动发现“索引指向了错误的 .MYD 行号”,这种错位只能靠业务层逻辑校验暴露
真正危险的不是报错,而是没报错却悄悄把性能问题埋下去——修复动作本身不难,难的是验证它是否在业务层面真正起效。











