17.18.2 InnoDB 恢复
本节描述了InnoDB
恢复。主题包括:
要将InnoDB
数据库恢复到当前时间点,从物理备份时刻开始,您必须在创建备份之前启用 MySQL 服务器的二进制日志记录。以便在恢复备份后应用从备份创建以来发生的更改。请参阅第9.5节,“Point-在时间(增量)恢复”。
如果您的数据库出现了损坏或磁盘故障,您必须使用备份进行恢复。在损坏的情况下,首先找到一个未损坏的备份。然后,从基础备份中恢复,然后使用mysqlbinlog和mysql从二进制日志文件中恢复自备份以来发生的更改。
在某些数据库损坏的情况下,只需要dump、drop和重新创建一个或几个损坏的表。您可以使用CHECK TABLE
语句来检查是否有表损坏,虽然CHECK TABLE
自然不能检测到每种可能的损坏类型。
在某些情况下,数据库页面损坏实际上是操作系统损坏其文件缓存所致,而磁盘上的数据可能是正确的。最好先尝试重新启动计算机。如果 MySQL 仍然无法启动,因为InnoDB
一致性问题,请查看第17.20.3节,“强制 InnoDB恢复”,了解如何在恢复模式下启动实例,这允许您将数据dump出来。
在MySQL服务器意外退出时,唯一的恢复要求是重新启动MySQL服务器。InnoDB
自动检查日志并对数据库进行回滚到当前状态。InnoDB
也自动回滚在崩溃时未提交的事务。
InnoDB
崩溃恢复 包括多个步骤:
-
表空间发现
表空间发现是
InnoDB
使用来识别需要redo日志应用的表空间。请参阅崩溃恢复期间的表空间发现。 -
redo日志 应用
redo日志应用是在初始化时进行的,且在接受任何连接之前。如果所有更改都已经从缓冲池 flush到表空间(
ibdata*
和*.ibd
文件)于崩溃或关闭时,redo日志应用将被跳过。InnoDB
也会在启动时如果redo日志文件丢失时跳过redo日志应用。-
当前的自动递增计数器值每次更改都会写入到redo日志中,这使其崩溃安全。在恢复过程中,
InnoDB
会扫描redo日志来收集计数器值更改并将更改应用于内存表对象。关于
InnoDB
如何处理自动递增值的更多信息,请见第17.6.1.6节,“InnoDB AUTO_INCREMENT处理”和InnoDB AUTO_INCREMENT计数器初始化。 -
当遇到索引树损坏时,
InnoDB
将写入redo日志中的一种损坏标记,使得损坏标记崩溃安全。InnoDB
还将内存中的损坏标记数据写入到引擎私有系统表中,每个检查点都执行一次。在恢复过程中,InnoDB
从这两个位置读取损坏标记,并在标记内存表和索引对象为损坏之前合并结果。 -
即使数据丢失也可以接受,不建议删除redo日志以加速恢复。只有在干净关闭服务器时,
innodb_fast_shutdown
设置为0
或1
时才考虑删除redo日志。
-
-
未完成的事务是指在unexpected exit或快速关闭时活动的所有事务。回滚一个未完成的事务可能需要三到四倍于事务活动时间的时间,取决于服务器负载。
您不能取消正在回滚的事务。在极端情况下,当回滚事务预计将花费非常长时间时,可能更快地从MySQL 8.3.0开始弃用。
-
Change buffer merge
将更改从change buffer(系统表空间的一部分)应用于次要索引的叶子页,随着索引页读取到缓冲池。
-
删除活动事务不可见的delete标记记录。
redo日志应用程序后的步骤不依赖于redo日志(除了用于记录写操作),并与正常处理并行进行。其中,只有未完成事务回滚是崩溃恢复的特殊步骤。插入缓冲区合并和purge在正常处理中进行。
重做日志应用后,InnoDB
尝试尽快接受连接,以减少停机时间。作为崩溃恢复的一部分,InnoDB
回滚未提交的事务或在服务器退出时处于XA PREPARE
状态的事务。回滚操作由背景线程执行,与来自新连接的事务并行执行。直到回滚操作完成,新连接可能会遇到与恢复事务产生的锁定冲突。
在大多数情况下,即使MySQL服务器在繁忙活动中突然崩溃,恢复过程将自动发生,不需要DBA干预。如果硬件故障或严重系统错误损坏了InnoDB
数据,MySQL可能无法启动。在这种情况下,请查看第17.20.3节,“强制InnoDB恢复”。
关于二进制日志和InnoDB
崩溃恢复的信息,请查看第7.4.4节,“二进制日志”。
崩溃恢复期间的表space发现
如果在恢复过程中,InnoDB
遇到自上一个检查点以来写入的重做日志,那么这些重做日志必须应用于受影响的表空间。恢复期间识别受影响表空间的过程称为表space发现。
表空间发现依赖于innodb_directories
设置,该设置定义了在启动时要扫描的目录,以便找到表空间文件。innodb_data_home_dir
、innodb_undo_directory
和datadir
定义的目录总是被追加到innodb_directories
参数值中,当InnoDB在启动时构建要扫描的目录列表时。这些目录无论是否指定了innodb_directories
设置,都将被追加。使用绝对路径或位于追加到innodb_directories
设置中的目录外的表空间文件,需要添加到innodb_directories
设置中。如果redo日志中引用的表空间文件在之前未被发现,则恢复将被终止。