myisam表报“table 'xxx' is marked as crashed”需先确认引擎,再用check table判断状态,ok则无需修复;否则用repair table在线修复,失败则停服务后用myisamchk -r -q离线修复;innodb不支持repair table,应查错误日志、尝试innodb_force_recovery导出数据。

遇到 Table 'xxx' is marked as crashed 怎么办
MyISAM 表报这个错,基本等于文件索引(.MYI)和数据(.MYD)对不上了,常见于异常断电、强制 kill mysqld、磁盘 I/O 故障。InnoDB 一般不会抛这个错误——它要么直接 crash,要么报 Corrupted page 或 innodb_force_recovery 相关提示。
实操建议:
- 先确认引擎:
SHOW CREATE TABLE xxx;—— 如果是ENGINE=MyISAM,才适用REPAIR TABLE;如果是InnoDB,跳过这步,别硬试 - 运行
CHECK TABLE xxx;看返回状态,Status: OK就不用修;Status: error或status: warning才需要下一步 -
REPAIR TABLE xxx;是最安全的在线修复方式,但仅限 MyISAM,且要求表没被其他线程锁死(否则会卡住或报Lock wait timeout) - 如果
REPAIR TABLE报Can't repair table, need rebuild,说明索引损坏严重,得用离线工具
myisamchk -r -q 什么时候必须用、怎么用
当 REPAIR TABLE 失败,或 MySQL 进程根本起不来(比如启动时卡在某个 MyISAM 表加载阶段),就得用 myisamchk —— 它不走 SQL 层,直接操作物理文件,所以必须停掉 mysqld。
实操建议:
- 先停服务:
sudo systemctl stop mysql(或mysqld,依发行版而定) - 定位文件路径:MyISAM 表文件默认在
/var/lib/mysql/<db_name>/<table_name>.MYI</table_name></db_name>,确认权限可读写 - 推荐命令:
myisamchk -r -q /var/lib/mysql/mydb/user.MYI——-r是修复,-q是“快速”,跳过部分校验,适合大多数轻度损坏 - 别乱加
-o(覆盖式重建):它会丢掉所有索引并重建,但主键/唯一约束定义还在,数据不丢;但如果表结构本身有误(比如字段类型错配),-o后可能更难恢复 - 修复完记得跑一次
myisamchk -c /var/lib/mysql/mydb/user.MYI做完整性检查
mysqlcheck 和 REPAIR TABLE 的关键区别
mysqlcheck 是命令行封装工具,本质还是调用 SQL 的 CHECK/REPAIR,但它支持批量、跨库、带密码参数,适合运维脚本;而 REPAIR TABLE 必须进 MySQL 客户端执行,适合单表临时救急。
实操建议:
- 修单个表:
mysqlcheck -r -u root -p mydb user,等价于REPAIR TABLE user; - 修整个库:
mysqlcheck -r -u root -p mydb,比一个个REPAIR省事,但注意它默认不修视图、存储过程 - 自动修复 + 检查组合:
mysqlcheck -c -a -r -u root -p mydb——-c检查,-a自动修复,-r强制修复(慎用,可能掩盖问题) - 别在生产高峰跑全库
mysqlcheck -o(-o是优化表,会锁表并重写 .MYD/.MYI),容易引发慢查询堆积
InnoDB 表报损坏别碰 REPAIR TABLE
InnoDB 不支持 REPAIR TABLE 命令,强行执行会报错 Repair operation is not supported for tables with engine InnoDB。它的损坏逻辑完全不同:不是文件头错位,而是页(page)级校验失败、undo 日志断裂、或 buffer pool 脏页刷盘异常。
实操建议:
- 第一反应不是修,是查日志:
tail -n 100 /var/log/mysql/error.log,重点找page number、space id、innodb_force_recovery提示 - 尝试启动时加配置:
innodb_force_recovery = 1(写进/etc/mysql/my.cnf的[mysqld]段),然后systemctl start mysql;若失败,再试 2~4,**别直接上 6** —— 6 会禁用 insert/update/delete,只允许 select,数据可能永久不可写 - 一旦能启,立刻用
mysqldump导出还能读的表,导完马上停服务,别等第二次崩溃 - 没有备份又无法导出?只能靠 Percona 的
innodb-tools(如ibdconnect、innochecksum)从.ibd文件里抢救记录,但这属于数据考古,成功率看运气
真正麻烦的不是怎么修,而是修完要不要换磁盘、要不要查内存 ECC 是否开启、要不要停掉所有 rsync 对 /var/lib/mysql 的轮询备份——InnoDB 损坏几乎从来不是 SQL 写错了,而是底层稳不住。










