REPAIR TABLE 不能在线执行,是阻塞式操作且仅适用于 MyISAM 表;InnoDB 表执行会报错,应使用 innodb_force_recovery + 逻辑导出或备份恢复。
REPAIR TABLE 在 MySQL 里到底能不能在线执行
不能,repair table 是阻塞式操作,会锁表(至少是读锁,多数情况下是写锁),在生产环境直接跑等于主动制造不可用。它只适用于 myisam 表,对 innodb 表执行会报错 error 1031 (hy000): table storage engine for 't' doesn't support repair —— 这点很多人踩坑后才意识到。
常见错误现象:执行 REPAIR TABLE 后应用卡住、慢查询堆积、监控显示 Table is locked;或者在 innodb_file_per_table=ON 的实例上误操作,发现命令根本不生效。
-
MyISAM表损坏时可尝试,但必须停写或切到从库操作 -
InnoDB表损坏不能靠它修复,得走innodb_force_recovery+ 逻辑导出/重建路径 - 5.7+ 默认引擎是
InnoDB,所以绝大多数场景下REPAIR TABLE是个“无效动作”
替代方案:InnoDB 表损坏了怎么救
真遇到 InnoDB 表页损坏(比如磁盘故障、突然断电后 mysqld 启不起来),优先看错误日志里有没有 Corrupted page 或 ibdata1 校验失败提示。这时候别硬重启,先设 innodb_force_recovery 参数启动实例,再尽快导出数据。
实操建议按最小安全级别试起:
- 从
innodb_force_recovery = 1开始,逐步加到6(值越大恢复越激进,但越可能跳过关键事务) - 设好后启动 MySQL,立刻用
mysqldump导出还能访问的库表,**不要做任何写操作** - 导出成功后,删掉旧数据目录,重装实例,再导入
- 如果连
1都启不动,说明系统表空间已坏,只能靠备份或mysqlbackup/Percona XtraBackup的物理备份恢复
检查表是否损坏的轻量方法(不锁表)
比起等故障爆发,日常该用非侵入方式巡检。对 InnoDB,CHECK TABLE 基本不锁表(5.7+ 默认只校验页 checksum,不扫全表),但要注意它不会自动修复,只是告诉你“坏了”。
使用场景:定期巡检脚本、主从延迟突增时快速排查、迁移前确认一致性。
-
CHECK TABLE t EXTENDED比默认模式更严格,会检查索引树结构,但耗时明显上升 -
CHECK TABLE对MyISAM会加读锁,大表慎用;对InnoDB影响极小,可放心加入运维脚本 - 返回结果里出现
status: OK才算通过;status: error或status: warning都得跟进
真正“在线修复”的可行路径
所谓在线,本质是用新表替换旧表,靠 ALTER TABLE ... ALGORITHM=INPLACE 或 pt-online-schema-change 实现。但这不是修损坏,而是重建——前提是表还能读。
比如索引失效、自增异常、统计信息严重偏差这类“软损坏”,可以用这种方式规避锁表风险:
-
ALTER TABLE t ENGINE=InnoDB会重建整张表,清除碎片和潜在页损坏痕迹(需确保磁盘空间 ≥ 当前表大小) - 用
pt-online-schema-change可控制并发、限速、校验一致性,适合大表,但要求有唯一键或主键 - 注意:如果表已经无法
SELECT,这些操作会直接失败,此时只能回退到备份或强制恢复流程
最容易被忽略的是:所有“修复”操作的前提,是损坏没波及到 mysql 系统库或 undo log。一旦 ibdata1 或 ib_logfile 损坏,整个实例就失去自愈能力,只能依赖备份。

















