[!前言]
根据日志恢复数据的流程涉及到两个主要阶段:重做(REDO)和撤销(UNDO)。这些过程利用了 MySQL 的二进制日志(binlog)和重做日志(redo log)

1. 日志文件概述

  • 二进制日志(binlog): 记录所有对数据库进行更改的操作,包括所有提交的事务。这些日志用于增量备份和数据恢复。
  • 重做日志(redo log): 记录所有将要执行的操作,用于在崩溃恢复过程中重新应用未提交的事务。
  • 撤销日志(undo log): 记录事务在执行过程中修改前的数据,用于在事务回滚时撤销未提交的更改。

2. 检查点

检查点(checkpoint)是数据库系统中的一个机制,用于定期将内存中的数据刷新到磁盘,并记录一个时间点。在 MySQL 中,检查点由 InnoDB 存储引擎管理,主要有以下作用:

  • 将缓冲池中的脏页(dirty pages)刷新到磁盘,减少崩溃恢复时需要重做的工作量。
  • 在检查点之后,只需从该检查点开始应用重做日志,减少恢复时间。

3. 恢复流程概述

当数据库崩溃或发生故障时,恢复流程通常包括以下几个步骤:

  1. 读取检查点信息: 从检查点文件读取最后一个检查点的位置。
  2. 应用重做日志(REDO): 从检查点位置开始,应用重做日志中的操作以恢复数据。
  3. 撤销未提交的事务(UNDO): 撤销在崩溃时未提交的事务,确保数据一致性。

4. 具体恢复流程

步骤 1:读取检查点信息

检查点文件(ib_logfile0ib_logfile1 等)包含最后一个检查点的位置。恢复过程从读取这些文件开始,确定从哪个位置开始应用重做日志。

步骤 2:应用重做日志(REDO)

从检查点开始,逐步应用重做日志中的操作。重做日志包含所有已提交和部分提交的事务操作。这些操作包括插入、更新和删除操作。重做日志的应用确保所有已提交的事务在数据恢复后仍然是提交状态。

REDO流程:
1. 从检查点位置开始读取重做日志。
2. 对每个日志条目,检查事务状态。
3. 如果事务已提交,重做该操作。
4. 如果事务未提交,暂时跳过。

步骤 3:撤销未提交的事务(UNDO)

在完成重做操作后,接下来是撤销未提交的事务。这部分操作依赖于撤销日志(undo log)。撤销日志记录了每个事务在修改数据前的状态。

UNDO流程:
1. 读取撤销日志,找到所有未提交的事务。
2. 按照撤销日志中的记录,逐步撤销每个未提交事务的操作。
3. 确保所有未提交的事务都被撤销,恢复数据的一致性。

恢复示例

假设数据库在执行过程中崩溃,以下是一个详细的恢复示例:

  1. 读取检查点信息:
    • 从检查点文件中读取最后一个检查点的位置,例如文件 ib_logfile0
  2. 应用重做日志(REDO):
    • 从检查点位置开始,读取重做日志文件 ib_logfile0ib_logfile1
    • 应用重做日志中的所有已提交事务,例如:
      • 事务 A:插入操作(已提交)。
      • 事务 B:更新操作(未提交)。
      • 事务 C:删除操作(已提交)。
  3. 撤销未提交的事务(UNDO):
    • 查找撤销日志,找到未提交的事务 B。
    • 撤销事务 B 的更新操作,将数据恢复到事务 B 之前的状态。
      通过以上步骤,数据库可以从崩溃中恢复,并确保数据的一致性和完整性。完整得流程图如下: