Forcing InnoDB Recovery
要调查数据库页面损坏,你可以通过SELECT ... INTO OUTFILE语句dump你的表。通常,以这种方式获取的数据是完整的。 严重的损坏可能会导致SELECT * FROM tbl_name 语句或者 InnoDB
后台操作出现意外的退出或断言,甚至导致 InnoDB
roll-forward recovery崩溃。这种情况下,你可以使用innodb_force_recovery选项来强制InnoDB
存储引擎启动时不进行后台操作,这样你就可以dump你的表了。比如,你可以在重启服务器前将如下行添加到[mysqld]
部分:
[mysqld]
innodb_force_recovery = 1
关于如何配置 option files, 参考Section 4.2.2.2, “Using Option Files”。
注意:
只有在紧急情况下可以设置 innodb_force_recovery 为大于0的值,这样你可以启动InnoDB
并dump你的表。在操作前,确保你已经拥有一份数据库的备份以防你需要重新创建。值>=4,可能会永久性的损坏数据文件。只有在另外一个独立的数据库物理副本上测试过innodb_force_recovery
>=4的值,才可以在生产环境上配置。 当强制InnoDB
recovery时,应该从innodb_force_recovery=1
开始,并根据需要递增该值。
innodb_force_recovery 默认值为0 (正常启动,不强制恢复)。 innodb_force_recovery 允许的非0值为1 to 6。 较大的值包含较小值的功能。例如,值3包括值1和值2的所有功能。
如果你可以在 innodb_force_recovery值设置为3或以下的时候dump表,那么你相对是安全的,只有损坏页面上的一些数据会丢失。4及更大的值被认为是危险的,因为数据文件可能会永久损坏。 值设置为6则被认为是极度危险的,因为数据库页处于过时状态,反过来可能会给 B-trees和其他数据库结构带来更多损坏。
作为安全措施,当innodb_force_recovery
大于0时,InnoDB
阻止 INSERT
, UPDATE
, or DELETE
操作。从MySQL5.6.15开始,innodb_force_recovery设置为4或更高将使innodb处于只读模式。
-
1
(SRV_FORCE_IGNORE_CORRUPT
)即使检测到损坏的page,服务器也要运行。尝试使SELECT * FROM
tbl_name
跳过损坏的索引记录和页,有助于dump表。 -
2
(SRV_FORCE_NO_BACKGROUND
)阻止master thread 和任何 purge threads 运行。如果在purge操作期间出现异常退出,该值会阻止它。
-
3
(SRV_FORCE_NO_TRX_UNDO
)在crash recovery之后,不运行事务rollbacks 。
-
4
(SRV_FORCE_NO_IBUF_MERGE
)阻止 insert buffer 合并操作。如果它们可能导致崩溃,那就不要做。不要计算table statistics。该值可能会永久损坏数据文件。使用该值,要准备好删除和重建所有的辅助索引。MySQL 5.6.15后,设置
InnoDB
为只读。 -
5
(SRV_FORCE_NO_UNDO_LOG_SCAN
)启动数据库时不查看 undo logs:
InnoDB
甚至将不完整的事务视为已提交。该值可能会永久损坏数据文件。MySQL 5.6.15后,设置InnoDB
为只读。 -
6
(SRV_FORCE_NO_LOG_REDO
)不执行 redo log 回滚。该值可能会永久损坏数据文件。将数据库页处于过时状态,可能会反过来造成B-trees和其他数据库结构的损坏。MySQL 5.6.15后,设置
InnoDB
为只读。
你可以使用SELECT
来dump表。设置innodb_force_recovery
值为 3 或更小,你可以DROP
or CREATE
表。MySQL 5.6.27后, DROP TABLE
在innodb_force_recovery
值大于3时也是支持的。
如果你直到一个给定的表可能会导致异常退出或回滚,你可以删除它。如果遇到由于批量导入或ALTER TABLE
失败而导致的失控回滚,你可以kill mysqld 进程,然后设置 innodb_force_recovery
为 3
来使数据库启动而不回滚,然后 DROP
导致失控回滚的表。
如果表数据损坏阻止了dump整个表的内容,使用ORDER BY primary_key DES 条件可能会导出损坏部分后面的表。
如果需要设置一个高的innodb_force_recovery
值来启动 InnoDB
,损坏的数据结构可能会导致复杂的查询 (包含 WHERE
, ORDER BY
, 或其他条件的查询) 失败。这种情况下,你只能使用基本查询 SELECT * FROM t 。