Documentation Home

14.19.2 InnoDB 恢复

本节介绍InnoDB恢复。主题包括:

时间点恢复

要将InnoDB数据库从进行物理备份时恢复到现在,您必须在启用二进制日志记录的情况下运行 MySQL 服务器,甚至在进行备份之前。要在还原备份后实现时间点恢复,您可以应用备份后发生的二进制日志中的更改。请参阅 第 7.5 节,“时间点(增量)恢复”

从数据损坏或磁盘故障中恢复

如果您的数据库损坏或发生磁盘故障,您必须使用备份执行恢复。在损坏的情况下,首先找到一个没有损坏的备份。恢复基本备份后,使用mysqlbinlogmysql从二进制日志文件进行时间点恢复,以恢复备份后发生的更改。

在某些数据库损坏的情况下,转储、删除和重新创建一个或几个损坏的表就足够了。您可以使用该 CHECK TABLE语句来检查表是否已损坏,但CHECK TABLE自然无法检测到每一种可能的损坏。

在某些情况下,明显的数据库页面损坏实际上是由于操作系统损坏了它自己的文件缓存,而磁盘上的数据可能是好的。最好先尝试重新启动计算机。这样做可能会消除看似数据库页面损坏的错误。InnoDB如果 MySQL 由于一致性问题 仍然无法启动,请参阅第 14.22.2 节,“强制 InnoDB 恢复”以了解以恢复模式启动实例的步骤,这允许您转储数据。

InnoDB 崩溃恢复

要从意外的 MySQL 服务器退出中恢复,唯一的要求是重新启动 MySQL 服务器。 InnoDB自动检查日志并将数据库前滚到现在。 InnoDB自动回滚崩溃时存在的未提交事务。在恢复期间,mysqld显示类似于以下的输出:

InnoDB: Log scan progressed past the checkpoint lsn 369163704
InnoDB: Doing recovery: scanned up to log sequence number 374340608
InnoDB: Doing recovery: scanned up to log sequence number 379583488
InnoDB: Doing recovery: scanned up to log sequence number 384826368
InnoDB: Doing recovery: scanned up to log sequence number 390069248
InnoDB: Doing recovery: scanned up to log sequence number 395312128
InnoDB: Doing recovery: scanned up to log sequence number 400555008
InnoDB: Doing recovery: scanned up to log sequence number 405797888
InnoDB: Doing recovery: scanned up to log sequence number 411040768
InnoDB: Doing recovery: scanned up to log sequence number 414724794
InnoDB: Database was not shutdown normally!
InnoDB: Starting crash recovery.
InnoDB: 1 transaction(s) which must be rolled back or cleaned up in
total 518425 row operations to undo
InnoDB: Trx id counter is 1792
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Progress in percent: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
InnoDB: Apply batch completed
...
InnoDB: Starting in background the rollback of uncommitted transactions
InnoDB: Rolling back trx with id 1511, 518425 rows to undo
...
InnoDB: Waiting for purge to start
InnoDB: 5.7.18 started; log sequence number 414724794
...
./mysqld: ready for connections.

InnoDB 崩溃恢复 包括几个步骤:

  • 表空间发现

    表空间发现是 InnoDB用于识别需要重做日志应用程序的表空间的过程。请参阅 崩溃恢复期间的表空间发现

  • 重做日志应用

    重做日志应用程序在初始化期间执行,在接受任何连接之前。 如果在关闭或崩溃时所有更改都从缓冲池刷新 到表空间ibdata*和文件),则跳过重做日志应用程序。如果重做日志文件在启动时丢失,也会跳过重做日志应用程序。 *.ibdInnoDB

    不建议删除重做日志来加速恢复,即使一些数据丢失是可以接受的。删除重做日志只应在干净关闭后考虑, innodb_fast_shutdown设置为 01

    有关 InnoDB用于识别需要重做日志应用程序的表空间的过程的信息,请参阅 崩溃恢复期间的表空间发现

  • 回滚未完成的 交易

    未完成的事务是在意外退出或快速关闭 时处于活动状态的任何事务 。回滚未完成事务所需的时间可能是事务中断前活动时间的三到四倍,具体取决于服务器负载。

    您不能取消正在回滚的事务。在极端情况下,当回滚事务预计需要特别长的时间时,从或更大InnoDBinnodb_force_recovery 设置开始可能会更快。3请参阅 第 14.22.2 节,“强制 InnoDB 恢复”

  • 更改缓冲区 合并

    将更改缓冲区( 系统表空间的一部分)中的更改应用到二级索引的叶页,因为索引页被读取到缓冲池。

  • 清除

    删除对活动事务不再可见的已删除标记的记录。

重做日志应用程序之后的步骤不依赖于重做日志(记录写入除外)并且与正常处理并行执行。其中,只有未完成事务的回滚是崩溃恢复所特有的。插入缓冲区合并和清除在正常处理期间执行。

重做日志应用后,InnoDB尝试尽早接受连接,以减少停机时间。作为崩溃恢复的一部分,InnoDB回滚XA PREPARE服务器退出时未提交或处于状态的事务。回滚由后台线程执行,与来自新连接的事务并行执行。在回滚操作完成之前,新连接可能会遇到与已恢复事务的锁定冲突。

在大多数情况下,即使 MySQL 服务器在繁重的活动中意外终止,恢复过程也会自动发生,无需 DBA 采取任何措施。如果硬件故障或严重的系统错误损坏了 InnoDB数据,MySQL 可能会拒绝启动。在这种情况下,请参阅第 14.22.2 节,“强制 InnoDB 恢复”

有关二进制日志和 InnoDB崩溃恢复的信息,请参阅 第 5.4.4 节,“二进制日志”

崩溃恢复期间的表空间发现

如果在恢复期间InnoDB遇到自上次检查点以来写入的重做日志,则必须将重做日志应用于受影响的表空间。在恢复期间识别受影响的表空间的过程称为 表空间发现

表空间发现是通过扫描从最后一个检查点到日志末尾的重做日志来执行的,以查找在 MLOG_FILE_NAME修改表空间页面时写入的记录。一条 MLOG_FILE_NAME记录包含表空间空间 ID 和文件名。

启动时,InnoDB打开系统表空间和重做日志。如果有自上次检查点后写入的重做日志记录,则根据MLOG_FILE_NAME记录打开受影响的表空间文件。

MLOG_FILE_NAME为所有持久表空间类型写入记录,包括每个表文件表空间、通用表空间、系统表空间和撤消日志表空间。

基于重做日志的发现具有以下特点:

  • *.ibd访问自上次检查点以来修改过的表空间文件。

  • *.ibd应用重做日志时,将忽略未附加到InnoDB实例的 表空间文件。

  • 如果MLOG_FILE_NAME系统表空间的记录与影响系统表空间数据文件名的服务器配置不匹配,则在应用重做日志之前恢复会失败并出现错误。

  • 如果日志的扫描部分中引用的表空间文件丢失,则拒绝启动。

  • *.ibd 仅当日志中存在文件删除重做日志记录 ( ) 时,才会忽略 丢失表空间文件的重做MLOG_FILE_DELETE日志。例如,表重命名失败可能导致 没有记录的丢失 *.ibd文件。 在这种情况下,您可以手动重命名表空间文件并重新启动崩溃恢复,或者您可以使用该选项MLOG_FILE_DELETE以恢复模式重新启动服务器 。当服务器以恢复模式启动时, innodb_force_recovery丢失的文件将被忽略。*.ibd

MySQL 5.7 中引入的基于重做日志的发现取代了早期 MySQL 版本中使用的目录扫描,以构建应用重做日志所需 的空间 ID 到表空间文件名”映射。