编辑
2026-01-19
笔记
00
请注意,本文编写于 54 天前,最后修改于 54 天前,其中某些信息可能已经过时。

目录

redo log
binlog
InnoDB 执行更新语句的流程

02 | 日志系统:一条 SQL 更新语句是如何执行的?

查询语句的执行流程,更新语句也会同样走一遍:

image.png

与查询流程不一样的是,更新流程会设计两个重要的日志模块:

  • 重做日志,redo log
  • 归档日志,binlog

redo log

WAL 的概念:每次更新都写入磁盘的话,效率会很慢,所有优化一下,先记录到日志,再在某个时机写入到磁盘,这就是 WAL,全称 Write-Ahead Logging。

具体到 InnoDB 来说,当有一条记录需要更新的时候,InnoDB 引擎先把更新数据记录到 redo log 并更新内存,然后 InnoDB 会在空闲的时候将数据写入到磁盘。

InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件 1 GB,那么一共可以记录 4GB 的更新操作数据。如果写满了就回到开头第一个文件循环写:

image.png

write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。

binlog

之前讲过,MySQL 的架构主要有 Server 层和存储引擎层。redo log 是 InnoDB 存储引擎特有的日志,而 binlog 是 Server 层的。

一开始 MySQL 没有 InnoDB,只有 MyISAM,但是 MyISAM 没有crash-safe 能力。Server 层的 binlog 只能用于归档。

redo log 和 binlog 的不同点:

  1. redo log 是 InnoDB 特有的,binlog 是 MySQL Server 层实现的,所有引擎都可以使用
  2. redo log 是物理日志,binlog 是逻辑日志
  3. redo log 是循环写,binlog 是追加写

InnoDB 执行更新语句的流程

  1. 执行器先找引擎拿到要更新的行,如果该行所在的数据页已经在内存中,则直接返回;否则从磁盘读取内存再返回
  2. 执行器对获取到的行数据修改值,调用引擎的写接口写入更新的值
  3. 引擎将新值更新到内存,记录到 redo log,标记状态为 prepare,然后告知执行器完成了。
  4. 执行器生成更新操作的 binlog,把 binlog 写入磁盘
  5. 执行器调用引擎的提交事务接口,引擎把将 redo log 标记改为 commit,更新完成

image.png

注意: 这个过程中,将写入 redo log 的过程拆分为 prepare 和 commit 的做法,就是两阶段提交。

本文作者:菜宝熊

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!