innodb表真损坏的判断依据是:启动失败、查询卡死、报error 2013或错误日志出现“innodb: database page corruption on disk”;需先用show table status确认引擎,再查error.log验证,禁用repair table和mysqlcheck --repair,唯一有效手段是逐级尝试innodb_force_recovery=1~6并导出数据后重建表。

怎么判断是不是 InnoDB 表真坏了
掉电后 MySQL 启动失败、查询卡死、SELECT 返回 ERROR 2013 (HY000): Lost connection to MySQL server during query,或者错误日志里反复出现 InnoDB: Database page corruption on disk——这些基本就是 InnoDB 底层页损坏了。别急着删 .ibd 文件,先用 SHOW TABLE STATUS LIKE 'table_name' 确认引擎是 InnoDB,再查 /var/log/mysql/error.log(Linux)里最近的报错段落。
为什么不能直接用 REPAIR TABLE 或 mysqlcheck
REPAIR TABLE 对 InnoDB 表无效,MySQL 会直接报 Table doesn't support repair;mysqlcheck --repair 在 InnoDB 上也只会跳过或报错。InnoDB 没有 MyISAM 那种“重建索引文件”的机制,它的恢复逻辑依赖事务日志(ib_logfile*)和数据页一致性校验。强行调用修复命令不仅没用,还可能掩盖真实损坏位置,干扰后续诊断。
innodb_force_recovery=1 到 6 怎么选、怎么试
这是唯一能绕过崩溃检查、让 mysqld 启动并读出部分数据的手段。必须在 my.cnf 的 [mysqld] 段下添加,改完必须重启服务:
-
innodb_force_recovery = 1:跳过回滚段初始化,适合事务未提交就断电的场景;能查SELECT * FROM t LIMIT 10,但全表扫可能失败 -
innodb_force_recovery = 2:额外禁用 purge 线程,避免后台写入触发坏页;导出时建议加WHERE id BETWEEN 1 AND 50分段拉取 -
innodb_force_recovery = 3及以上:逐步禁用 insert buffer、rollback segment、甚至不加载二级索引;值越高,可读数据越少,且INSERT/UPDATE/DELETE全部被禁用
不要一上来就设成 6。从 1 开始试,每次只升一级,只要能 SELECT 出关键数据就立刻导出,别等“完全恢复”——InnoDB 的损坏往往是局部页失效,不是全表不可读。
导出后重建表的关键动作
用 mysqldump -u root -p --no-create-info --skip-triggers database table > data.sql 导出数据(--no-create-info 避免带原表结构,因为结构可能已损坏);然后手动 DROP TABLE,用原始 CREATE TABLE 语句重建(别用 mysqldump --no-data 导出的,它可能含损坏元数据);最后导入 data.sql。修复完成后务必校验:SELECT COUNT(*) 对比行数、抽样查几条带时间戳或业务主键的记录是否连续、用 CHECK TABLE 确认状态为 OK。
真正容易被忽略的是:修复后必须把 innodb_force_recovery 从配置里删掉或设为 0,否则 MySQL 拒绝写入,所有 DML 都会失败——这不是警告,是硬限制。











