myisam表报“table is marked as crashed”时,先确认引擎为myisam,再停写入、用mysqlcheck或repair table修复;修复后需flush tables、analyze table,必要时重启mysqld。

MyISAM表突然报错“Table is marked as crashed”怎么办
直接执行 REPAIR TABLE,但必须先确认表引擎确实是 MyISAM —— InnoDB 表用这个命令会报错 Storage engine for the table doesn't support repair。常见触发场景:MySQL 异常关闭、磁盘满、kill -9 强制终止 mysqld 进程。
- 先查引擎:
SHOW CREATE TABLE `table_name`;或SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA='db_name' AND TABLE_NAME='table_name'; - 如果引擎是 MyISAM,且错误日志里出现
Client requested master to start replication from impossible position或record-file is crashed,基本可锁定是索引或数据文件损坏 - 别急着连上 MySQL 就修——先停写入,避免修复中途又被写坏
mysqlcheck 命令比 REPAIR TABLE 更适合批量检查
mysqlcheck 是命令行工具,能绕过连接 MySQL 的权限限制(比如你只有 shell 权限但没 GRANT 权限),也支持批量操作。它本质是调用 SQL 的 CHECK TABLE / REPAIR TABLE,但封装了更安全的默认行为。
- 只检查不修:
mysqlcheck -c database_name table_name,输出含status: OK或error字样 - 自动修复:
mysqlcheck -r database_name table_name,等价于REPAIR TABLE,但加了--safe-recover模式(跳过损坏索引重建,优先保数据) - 强制使用快速修复(跳过排序):
mysqlcheck -r --quick database_name table_name;但若提示Incorrect key file,就得换--safe-recover - 注意:
mysqlcheck默认用root@localhost连接,如果 MySQL 绑定的是 socket 文件而非 TCP,得加-S /var/run/mysqld/mysqld.sock
REPAIR TABLE 三种模式的区别和选法
REPAIR TABLE 支持 QUICK、EXTENDED、USE_FRM 三种模式,不是所有情况都能混用。选错可能修完还是报错,甚至丢数据。
-
REPAIR TABLE tbl_name QUICK:只修复索引文件(.MYI),不碰数据文件(.MYD)。适用于索引损坏但数据完好,速度最快 -
REPAIR TABLE tbl_name EXTENDED:逐行重建索引,适合QUICK失败后尝试。但对大表极慢,还可能因内存不足中断 -
REPAIR TABLE tbl_name USE_FRM:用 .FRM 表结构文件重建 .MYI,完全丢弃原索引。仅当 .MYI 彻底损坏且无备份时才用,不恢复索引内容,后续要手动ANALYZE TABLE - 常见错误:
Can't create new tempfile通常因 tmpdir 空间不足,需改tmpdir=/path/to/big/disk再试
修复后为什么 SELECT 还卡住或返回空?
修完不代表万事大吉。MyISAM 是表级锁,修复过程会锁表,而某些修复残留状态会让查询误判为“正在修复中”,或者统计信息未更新导致优化器走错执行计划。
- 执行
FLUSH TABLES清掉缓存,再ANALYZE TABLE tbl_name更新索引统计 - 如果仍卡在
Repair by sorting状态,查SHOW PROCESSLIST,看是否有Repair with keycache长时间运行——这是EXTENDED模式在低内存下退化的行为,建议停服务后用myisamchk离线修复 - 离线修复命令:
myisamchk -r -v /var/lib/mysql/db_name/tbl_name.MYI(注意路径和文件名大小写) - 最易被忽略的一点:修复后没重启 MySQL,旧的损坏句柄还在内存里,
SELECT可能读到脏页缓存 —— 重启 mysqld 是最稳妥的收尾动作











