咨询微信: dbservice1234 7 x 24 在线支持!

强制MySQL InnoDB恢复参数innodb_force_recovery

强制MySQL InnoDB恢复参数innodb_force_recovery

强制InnoDB恢复

为了研究数据库页损坏,你能用SELECT … INTO OUTFILE从数据库中转储表。通常,以这种方式获得的大部分数据是完整的。严重的损坏可能导致SELECT* FROM tbl_name语句或InnoDB的后台操作崩溃或断言,甚至造成InnoDB前滚恢复崩溃。 在这样的情况下,可以使用innodb_force_recovery选项强制InnoDB存储引擎启动同时阻止后台操作运行,这样你就能转储表了。例如,你可以在重新启动服务器之前添加以下行到选项文件的[mysqld]部分:

[mysqld]

innodb_force_recovery = 1

警告

只有在紧急情况下将innodb_force_recovery设为大于0的值,你才能启动InnoDB并转储表。在进行此操作之前,确保你有数据库的备份副本,以备需要重建它。4及以上的值可以永久破坏数据文件。只有在数据库的独立物理副本的成功地测试了设置,才能在生产服务器实例使用4及以上的innodb_force_recovery设置。当强制InnoDB恢复,你应该总是以innodb_force_recovery=1启动,且仅在需要时增加值。

innodb_force_recovery默认为0(没有强制恢复的正常启动)。对于innodb_force_recovery允许的非零值是1至6。较大值包括较小值的功能。例如,为3的值包括所有的值1和2的功能。

 

如果你能以innodb_force_recovery为3或更低值转储你的表,那么你是比较安全的,只有在损坏的个人页的一些数据会丢失。4或更大的值被认为是危险的,因为数据文件可以被永久地损坏。值6被认为是严重的,数据库页被留在一个陈旧的状态,这反过来又可能带给B-trees和其它数据库结构更多的损坏。

 

作为一个安全措施,InnoDB 在innodb_force_recovery大于0时阻止INSERT,UPDATE或DELETE操作。对于MySQL5.6.15,将innodb_force_recovery设为4或更高会让InnoDB处于只读模式。

  • 1 (SRV_FORCE_IGNORE_CORRUPT)

即使服务器检测到损坏的页仍让它运行。试图使SELECT* FROM tbl_name跳过损坏的索引记录和页,这样有助于转储表。

 

  • 2 (SRV_FORCE_NO_BACKGROUND)

阻止主线程和任何清除线程的运行。如果崩溃会在清除操作中发生,该恢复值会阻止它。

 

  • 3 (SRV_FORCE_NO_TRX_UNDO)

不要在崩溃恢复后运行事务回滚。

 

  • 4 (SRV_FORCE_NO_IBUF_MERGE)

阻止插入缓冲合并操作。如果它们会导致崩溃,不要做这些。不计算表统计。这个值可以永久损坏数据文件。使用这个值后,准备号删除并重建所有辅助索引。在MySQL5.6.15中,设置InnoDB为只读。

 

  • 5 (SRV_FORCE_NO_UNDO_LOG_SCAN)

在启动数据库时不查看撤消日志:InnoDB将即使未完成的事务也作为已提交。这个值可以永久损坏数据文件。在MySQL5.6.15中,设置InnoDB为只读。

 

  • 6 (SRV_FORCE_NO_LOG_REDO)

不要通过恢复对重做日志进行前滚。这个值可能永久损坏数据文件。数据库页被留在一个陈旧的状态,这反过来又可能带给B-trees和其它数据库结构更多的损坏。在MySQL5.6.15中,设置InnoDB为只读。

 

你可以从表中SELECT来转储它们。innodb_force_recovery的值为3或更低,你可以DROPCREATE表。在MySQL 5.6.27中,DROP TABLE还受大于3的innodb_force_recovery值支持。

 

如果你知道一个给定表在回滚造成崩溃,你可以将其删除。如果遇到所造成失败的大规模导入的失控回滚或ALTER TABLE,你可以杀掉mysqld进程,并设置innodb_force_recovery3使数据库启动而不回滚,然后DROP导致失控回滚的表。

 

如果表数据中的损坏阻止你转储整个表的内容,带ORDER BY primary_key DESC子句的查询能够转储损坏部分后的表的部分。

 

如果一个高innodb_force_recovery值需要启动InnoDB,可能有被破坏的数据结构,可能导致复杂查询(含有WHEREORDER BY或其他子句的查询)失败。在这种情况下,你可能只能运行基本的SELECT* FROM t查询。