能读取就别停服务,先用check table确认损坏,再用repair table在线修复——但仅对myisam表有效;innodb表执行该命令会报错“storage engine doesn't support repair”,须改用innodb_force_recovery导出数据或备份恢复。

直接回答:能读取就别停服务,先用 CHECK TABLE 确认损坏,再用 REPAIR TABLE 在线修复——但仅对 MyISAM 表有效;InnoDB 表执行 REPAIR TABLE 会报错,必须换路子。
怎么确认表真坏了,而不是权限或语法问题
很多“无法读取”其实是误判。先排除干扰:
-
CHECK TABLE your_db.your_table;—— 返回Msg_text含is marked as crashed、Incorrect key file或状态不是OK,才算确认损坏 - 查错误日志:
/var/log/mysql/error.log(Linux)或data/hostname.err(Windows),搜crashed、corrupt、failed to open - 执行
SHOW TABLE STATUS LIKE 'your_table';,看Comment列是否含Crashed—— 这比SELECT报错更早暴露问题
REPAIR TABLE 能修什么、不能修什么
REPAIR TABLE 是 SQL 层命令,只对 MyISAM 表起作用;InnoDB 表执行它会直接报错:Storage engine for the table doesn't support repair。
- MyISAM 可用的模式:
-
REPAIR TABLE your_table;—— 默认模式,快但不彻底,适合轻度索引错位 -
REPAIR TABLE your_table EXTENDED;—— 重建全部索引,慢但可靠,适合Key block size is wrong类错误 -
REPAIR TABLE your_table USE_FRM;—— 当.MYI完全丢失时,靠.FRM结构文件重建索引(.MYD得还在)
-
- InnoDB 表别试这个命令——它不支持。强行执行只会浪费时间,还可能掩盖真正问题(比如 ibdata1 损坏或 redo log 异常)
CHECK TABLE 和 REPAIR TABLE 的常见坑
这两个命令看着简单,但踩错一步就白忙:
-
CHECK TABLE对大表会锁表并阻塞写入,生产环境慎用;若表超 10GB,优先改用mysqlcheck -c(它默认不锁表) -
REPAIR TABLE需要ALTER权限,且执行期间该表被加写锁——其他连接 SELECT 可能卡住,UPDATE/INSERT 全部排队 - 修复后务必再跑一次
CHECK TABLE,不能只看返回 “OK” 就完事;要对比修复前后Data_length和Index_length是否突变,防数据静默丢失 - 如果
REPAIR TABLE执行卡住超过 5 分钟,或反复报Can't repair table,说明已超出在线修复能力,得切到离线方案(myisamchk或备份恢复)
为什么你修完还是读不了——关键在引擎判断
很多人修完发现 SELECT 依然报错,根源常被忽略:没确认表用的是什么引擎。
- 运行
SHOW CREATE TABLE your_table;,第一行就写着ENGINE=MyISAM还是ENGINE=InnoDB - MyISAM 表损坏多见于断电、强制 kill mysqld,现象是
Table is marked as crashed;InnoDB 表极少“标记为崩溃”,更多是启动失败、错误日志里出现InnoDB: Database page corruption - 一旦确认是 InnoDB,立刻放弃
REPAIR TABLE,转去检查innodb_force_recovery参数和最近的mysqldump备份——这才是它真正的修复路径
最常被跳过的动作是:修之前没备份原表文件(.MYI/.ibd)。哪怕只是复制一份到临时目录,也能在修复失败时退回原点。线上操作,宁可多花两分钟,别省这一步。











