InnoDB表空间损坏无法修复,只能抢救数据并重建实例;需先通过错误日志关键词(如“Corrupted page found”“Tablespace is missing”“MY-012562”)区分物理损坏、LSN不一致或文件丢失,再备份后逐级启用innodb_force_recovery=1~3导出数据,成功后必须删除参数并重建系统表空间。

InnoDB表空间损坏不能修复,只能抢救数据——没有REPAIR TABLE这种操作,也不存在“修好后继续用”的路径。唯一可行的操作是启用innodb_force_recovery导出还能读的数据,再重建表或整个实例。
怎么确认是表空间损坏,而不是文件丢失或权限问题
先别改配置,直接查错误日志(路径由SHOW VARIABLES LIKE '%log_error%'确定):
- 出现
Corrupted page found、Database page corruption on disk或Failed to read page→ 物理页损坏,真坏了 - 报
Tablespace is missing for table或Operating system error number 2→.ibd被删、移走或chmod 000了 - 看到
MY-012562或MY-013183→ LSN不一致或断言失败,多由断电引起,不一定需要innodb_force_recovery
顺手跑一次:mysqlcheck --check --extended --all-databases。如果只有个别表报error: record is corrupted,说明是单个.ibd损坏;若大面积报错,优先怀疑ibdata1或系统表空间元数据层崩溃。
innodb_force_recovery该设几?从1开始试,别跳
这个参数不是越大越好,也不是设了就能导出全部数据。它从1到6逐级放宽崩溃恢复限制,但每升一级,跳过的结构就越多:
-
innodb_force_recovery = 1:跳过损坏的索引记录,允许SELECT,仍可能接受INSERT/UPDATE(不推荐) -
innodb_force_recovery = 2:停掉purge线程和change buffer合并,只允许SELECT,禁止写操作 -
innodb_force_recovery = 3:忽略未提交事务,ACID保障失效,但能绕过事务回滚失败导致的启动卡死(多数断电场景首选) -
innodb_force_recovery = 4及以上:禁用插入缓冲、清除线程甚至重做日志应用,极易引发二次崩溃,生产环境慎用
实操建议:
- 必须从1开始试,不能跳着设——2可能比1更卡死,因为跳过的恢复逻辑不同
- 加完配置后,一定要停掉MySQL(
systemctl stop mysqld),再手动启动:/www/server/mysql/bin/mysqld --defaults-file=/www/server/mysql/etc/my.cnf & - 启动成功后立刻执行:
mysqldump -u root -p --skip-lock-tables --routines --triggers database_name > db.sql;导出卡住就降级重试,别硬扛 - 导完马上注释掉
innodb_force_recovery行,否则写操作全被拒绝
导出时为什么总卡住?关键参数漏了
就算innodb_force_recovery = 3能连上,mysqldump默认会触发LOCK TABLES,而 recovery 模式下锁机制异常,导致超时或断连。
- 必须加
--skip-lock-tables,否则大概率卡死 -
--single-transaction在recovery模式下常失效,改用--lock-tables=false并接受部分不一致 - 若导出卡在某张表,不要死磕,降低 recovery 级别重试
- 导出命令示例:
mysqldump -u root -p --skip-lock-tables --routines --triggers --all-databases > /root/all.sql
最易被忽略的一点:innodb_force_recovery启用后,MySQL会拒绝所有写操作,包括DROP、TRUNCATE甚至CREATE TEMPORARY TABLE。这意味着你无法在原实例里重建表——导出完必须新建库、建表、再导入。任何试图“在线修复”的想法都会卡在第一步。


















