myisam表崩溃后必须人工干预修复,不能自动恢复;应先用check table和show table status验证损坏实锤,再据损坏程度选用repair table quick/extended/use_frm模式,修复后须二次校验、检查.frm文件完整性及权限。

MyISAM 表崩溃后不能靠重启自动恢复,必须人工干预;REPAIR TABLE 是首选方案,但用错模式或忽略前置条件反而会让表彻底不可读。
如何快速确认 MyISAM 表真损坏了
别只看错误信息就动手修。MySQL 报 Table is marked as crashed and should be repaired 或 Incorrect key file for table,只是“疑似”,得验证。
- 先执行
CHECK TABLE table_name;,看返回的Msg_type是否为Error或Warning,Msg_text里含crashed才算实锤 - 查
SHOW TABLE STATUS LIKE 'table_name';,重点看两处:Engine必须是MyISAM(InnoDB 表执行REPAIR TABLE会静默忽略);Comment列若写有crashed,基本可断定物理文件已脱节 - 翻错误日志:
show variables like '%log_error%';找到路径,再grep -i crashed /var/lib/mysql/xxx.err,确认是否在启动或查询时反复触发
REPAIR TABLE 的三种模式怎么选才不翻车
默认 REPAIR TABLE table_name; 实际等价于 QUICK 模式——它只重写 .MYI 索引文件,不动 .MYD 数据文件。快是快,但失败率高,尤其当数据页也出问题时。
- 轻度损坏(仅索引错乱、查询报
Incorrect key file):用REPAIR TABLE table_name QUICK;,秒级完成 - 中度损坏(
REPAIR TABLE默认失败,或CHECK TABLE提示record-file is crashed错误码 127):必须上EXTENDED模式:REPAIR TABLE table_name EXTENDED;,它会逐行读取.MYD并重建整套索引,但要求磁盘剩余空间 ≥ 表大小的 2 倍 - 重度损坏(
.MYI文件丢失、或myisamchk -s直接报Key block size is wrong):只能靠USE_FRM强制重建:REPAIR TABLE table_name USE_FRM;,它完全抛弃原.MYI,仅按.frm结构生成空索引——修完表能查,但所有索引失效,后续得手动ANALYZE TABLE或ALTER TABLE ... ADD INDEX
为什么 myisamchk 修复常失败,以及怎么绕过
myisamchk 是离线工具,但很多人卡在第一步:停不了服务,或停了也修不成功。根本原因不是命令不会敲,而是环境没理清。
- 常见报错
Can't change size of file,90% 是磁盘空间不足或 inode 耗尽,不是文件损坏本身。务必先跑df -h和df -i,尤其注意 MySQL 数据目录挂载点 - 执行前没 flush 表或没停 mysqld,导致
myisamchk读到脏数据。正确流程是:mysqladmin flush-tables→systemctl stop mysql→ 进入数据库目录(如/var/lib/mysql/dbname/)→myisamchk -r table_name.MYI - 如果
myisamchk -r仍失败,换--safe-recover --force组合:myisamchk --safe-recover --force table_name.MYI。它会跳过坏块,尽力提取还能读的行,比 SQL 层修复更底层 - 千万别在运行中的 mysqld 上直接跑
myisamchk(除非明确启用了 external locking),否则可能引发二次损坏
修复后最容易被忽略的三件事
修完不是终点。MyISAM 没事务、没回滚,修复过程本身就有风险,收尾动作不到位,等于白干。
- 立刻再跑一次
CHECK TABLE table_name;,确认返回全是OK。别信REPAIR TABLE成功提示就完事——它可能只修了部分索引 - 检查
.frm文件是否异常:ls -l table_name.frm看大小是否合理(几百字节到几 KB),若为 0 字节或超 1MB,说明结构定义已损,USE_FRM也救不回来,只能从备份恢复该文件 - 权限别忘改:
chown mysql:mysql table_name.*。手动拷贝或 root 操作留下的属主错误,会导致后续查询报Can't open file,连CHECK TABLE都执行不了











