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

不能直接“修复”损坏的 InnoDB 表空间,只能抢救数据并重建实例——innodb_force_recovery 是只读逃生通道,不是修复开关。
怎么确认真是 InnoDB 物理损坏,而不是日志不一致或文件丢失?
先别动配置。打开错误日志(通常是 /var/log/mysql/error.log 或 /var/lib/mysql/hostname.err),翻到最开头几行,盯住这些关键词:
-
InnoDB: Database page corruption on disk→ 物理页损坏,真坏了 -
MY-012562或MY-013183→ LSN 不匹配或断言失败,典型非正常关机后遗症 -
Tablespace is missing for table→.ibd文件被删、移走或权限为 000 -
InnoDB: The log sequence number in ibdata1 does not match→ redo log 和数据文件 LSN 不一致,常可重建日志解决,不一定需要innodb_force_recovery
如果日志里夹着 Table 'xxx' is marked as crashed,那是 MyISAM 表坏了,走 mysqlcheck --repair,别碰 InnoDB 恢复参数。
备份完再试 innodb_force_recovery = 1,别跳级
修复前不备份 = 主动删库。执行:
systemctl stop mysqld cp -r /var/lib/mysql /var/lib/mysql_backup_$(date +%Y%m%d_%H%M)
确认备份存在且 ibdata1 大小合理(通常几十 MB 到几 GB)。然后编辑 /etc/my.cnf 的 [mysqld] 段,只加一行:
[mysqld] innodb_force_recovery = 1
重启服务后立刻验证:
- 用
mysql -u root -p -e "SHOW DATABASES;"看是否返回库名列表 - 若报
ERROR 2013 (HY000)或卡住,2 分钟内停服务,改=2再试 - 级别 3(
innodb_force_recovery = 3)是多数断电场景的首选:跳过事务回滚,允许SELECT,但禁止所有写操作 - 别设
=6开局,它可能让还能读的表也变不可见;更别同时写多个级别或加注释行,MySQL 会解析失败
导出时必须加 --skip-lock-tables,否则大概率卡死
就算 innodb_force_recovery = 3 能连上,mysqldump 默认会触发 LOCK TABLES,而 recovery 模式下锁机制异常,导致超时或断连。
- 必须加
--skip-lock-tables,例如:mysqldump -u root -p --skip-lock-tables --routines --triggers database_name > db.sql -
--single-transaction在 recovery 模式下常失效,别依赖它保证一致性 - 如果全库导出卡在某张表,立刻切到单库导出:
mysqldump -u root -p dbname > dbname.sql - 若
mysqldump报Lost connection to MySQL server,换SELECT ... INTO OUTFILE或用mysqlpump
导出成功后第一件事:注释掉 my.cnf 里的 innodb_force_recovery 行,删掉 ib_logfile* 和 ibdata1(确保无其他实例共用),重启让 MySQL 自建干净系统表空间——带该参数长期运行等于把数据库钉在逻辑不一致状态,下次启动必崩。











