myisam表出现“table is marked as crashed”是物理损坏的明确信号,因其无事务日志和崩溃恢复机制,异常断电、kill -9等会导致.myd与.myi文件脱节;innodb依赖ib_logfile和双写缓冲,崩溃后可自动恢复,故几乎不报此提示。

这是 MyISAM 表物理损坏的明确信号,不是误报,必须人工干预;InnoDB 表几乎不会出现该提示。
为什么只出现在 MyISAM 表上
MyISAM 没有事务日志和崩溃恢复机制,写操作直接落盘。一旦进程被 kill -9、磁盘满、异常断电或硬件故障,.MYD(数据)和 .MYI(索引)文件极易脱节或写入不完整,MySQL 启动时会检查并主动在 SHOW TABLE STATUS 的 Comment 列中标记 crashed。而 InnoDB 依赖 ib_logfile 和双写缓冲(doublewrite buffer),崩溃后能自动前滚/回滚,错误日志里更常见的是 InnoDB: Database page corruption 或服务根本无法启动。
错误日志里看到这行,下一步必须做三件事
不要跳过验证直接修表:
- 执行
SHOW VARIABLES LIKE '%log_error%'确认日志路径,再用grep -i 'crashed\|corrupt' /var/lib/mysql/error.log查是否真有对应表名的记录 - 运行
SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'table_name';确保引擎确实是MyISAM—— 很多用户查了半天,结果表是InnoDB,根本不用REPAIR TABLE - 检查
ls -l /var/lib/mysql/db_name/table_name.*:三个文件(.frm、.MYD、.MYI)是否都存在且属主为mysql:mysql;.frm文件大小是否异常(0 字节或 >1MB 基本可判损坏)
REPAIR TABLE 执行失败的常见原因
REPAIR TABLE 是在线修复命令,但对环境很敏感:
- 磁盘剩余空间不足:要求空闲空间 ≥ 表
.MYD文件大小的 2 倍,否则中途失败并可能让表彻底不可读 - 表正被其他会话写入:即使只是长查询持有读锁,
REPAIR TABLE也可能卡住或返回Operation failed -
.MYI严重损坏时,REPAIR TABLE会报Last repair failed,此时必须停 MySQL,改用myisamchk -r -q /path/to/table.MYI - MySQL 用户对数据目录无写权限,或 SELinux/AppArmor 拦截了文件操作,错误日志里通常伴随
Permission denied
最易被忽略的细节:.frm 文件其实很脆弱
很多人以为只有 .MYD 和 .MYI 会坏,但 .frm 是二进制元数据容器,跨版本复制(如从 MySQL 5.7 拷 .frm 到 8.0 实例)、用文本编辑器误保存、甚至 chown 时漏掉它,都会触发 ERROR 1033 (HY000): Incorrect information in file: './db/t.frm' —— 此时 REPAIR TABLE 根本不会执行,连错误提示都不一样。验证方式只有两个:CHECK TABLE 返回 Can't open file,或对比同结构表的 .frm 文件大小。











