MySQL 日志模块概述

1. Redo Log 与 Binlog

在 MySQL 中,日志模块主要包括两种:Redo LogBinlog。它们分别位于不同的层次,承担不同的职责。

1.1 Redo Log

  • 位置:特有于 InnoDB 引擎。
  • 类型:物理日志,记录具体的物理修改(如“在某个数据页上做了什么”)。
  • 写入方式:循环写入,空间固定,写满后会覆盖旧数据。

1.2 Binlog

  • 位置:属于 MySQL Server 层,所有存储引擎均可使用。
  • 类型:逻辑日志,记录原始逻辑操作(如“给 ID=2 的 c 字段加1”)。
  • 写入方式:追加写入,文件写满后切换到下一个文件,不会覆盖先前的日志。

2. Update 语句执行流程

在执行 Update 语句时,执行器与 InnoDB 引擎的内部流程如下:

  1. 查找数据

    • 执行器通过主键 ID 查找 ID=2 的行。
    • 如果数据页已在内存中,直接返回;否则,从磁盘读取数据到内存。
  2. 更新数据

    • 执行器将获取的值加1,生成新数据。
    • 调用引擎接口,将新数据写入内存,并记录到 Redo Log(此时处于 prepare 状态)。
  3. 生成 Binlog

    • 执行器生成该操作的 Binlog,并将其写入磁盘。
  4. 提交事务

    • 执行器调用引擎的提交事务接口,将 Redo Log 的状态更改为提交(commit),完成更新。

3. 两阶段提交

3.1 原因

两阶段提交的主要目的是确保 Redo Log 和 Binlog 之间的逻辑一致性,尤其在数据恢复时至关重要。

3.2 数据恢复过程

假设需要恢复到某个特定的时间点,过程如下:

  1. 找到最近的一次全量备份。
  2. 从备份开始,依次重放 Binlog,直到恢复到指定的时间点。

3.3 不一致的风险

不使用两阶段提交可能导致以下问题:

  • 先写 Redo Log 后写 Binlog

    • 如果在写完 Redo Log 后崩溃,恢复后数据已更新,但 Binlog 中缺少对应记录,导致恢复的数据不一致。
  • 先写 Binlog 后写 Redo Log

    • 如果在写完 Binlog 后崩溃,恢复后数据未更新,但 Binlog 中已记录更新操作,导致恢复的数据与原库不一致。

4. 总结

两阶段提交确保了 Redo Log 和 Binlog 的状态逻辑一致,为数据库的可靠性和一致性提供了保障。这在误操作恢复和系统扩容时尤为重要。