MySQL 更新(UPDATE)语句的执行流程,包括 存储引擎内部的文件写入 和 主从复制的同步过程

一、MySQL 执行 UPDATE 的整体流程

假设我们执行:

UPDATE user SET name = 'Tom' WHERE id = 1;

1. 客户端发送 SQL 到 MySQL Server

  • 客户端通过 连接器(Connection)发送 SQL。
  • MySQL Server 层接收到 SQL,进入 查询缓存(8.0 已废弃) 检查是否有缓存结果(更新语句一般不会命中缓存)。

2. 解析与优化

  • 解析器(Parser):将 SQL 转换成语法树。
  • 优化器(Optimizer):选择最优的执行计划(比如用哪个索引)。
  • 执行器(Executor):调用存储引擎接口执行更新。

3. InnoDB 存储引擎执行更新

假设表使用 InnoDB 引擎,更新流程如下:

3.1 查找数据页
  • 根据索引定位到对应的 数据页(Data Page)
  • 如果数据页不在 Buffer Pool(内存缓存区),则从 数据文件(.ibd 或共享 ibdata) 读取到 Buffer Pool。
3.2 加锁
  • 对匹配的记录加 行锁(Record Lock)或 间隙锁(Gap Lock),保证事务隔离。
3.3 修改内存数据
  • 在 Buffer Pool 中修改记录的值(name 改为 'Tom')。
  • 记录到 Undo Log(回滚日志),用于事务回滚和 MV***。
3.4 写入 Redo Log
  • 将修改操作记录到 Redo Log Buffer(内存)。
  • Redo Log 是物理日志,记录“在哪个数据页做了什么修改”。
  • Redo Log Buffer 会周期性或事务提交时刷盘到 redo log 文件(ib_logfile0/ib_logfile1)
3.5 写入 Binlog
  • MySQL Server 层生成 Binlog(逻辑日志),记录 SQL 或行级变更。
  • Binlog 先写到 Binlog Cache(内存),事务提交时刷盘到 binlog 文件(mysql-bin.xxxx)

二、事务提交阶段

MySQL 使用 两阶段提交(2PC) 保证 Binlog 和 Redo Log 一致性:

  1. 阶段 1:写 Redo Log 并标记为 prepare 状态(刷盘)。
  2. 阶段 2:写 Binlog(刷盘),然后将 Redo Log 标记为 ***mit 状态。

这样保证:

  • 如果写 Binlog 失败,Redo Log 也不会提交(事务回滚)。
  • 如果写 Binlog 成功但崩溃,恢复时可用 Redo Log 重做。

三、主从复制流程

假设 MySQL 开启了 主从复制(基于 Binlog):

1. 主库写 Binlog

  • 主库事务提交时,Binlog 文件中追加一条更新记录。

2. 从库 I/O 线程拉取 Binlog

  • 从库的 I/O 线程 连接主库,读取新的 Binlog 内容。
  • 将 Binlog 写入从库的 Relay Log(中继日志)

3. 从库 SQL 线程执行 Relay Log

  • 从库的 SQL 线程 读取 Relay Log,按顺序执行更新。
  • 执行过程和主库一样:更新 Buffer Pool → 写 Redo Log → 写 Binlog(如果从库也开启 Binlog)。

四、涉及的文件写入顺序

我帮你整理成一个表格,方便你快速记忆:

阶段 文件/缓存 作用
查找数据 .ibd / ibdata 数据文件 存储表数据页
修改内存 Buffer Pool 内存缓存数据页
记录回滚信息 Undo Log(内存+磁盘) 支持事务回滚和 MV***
记录物理变更 Redo Log Buffer → ib_logfile0/1 崩溃恢复
记录逻辑变更 Binlog Cache → mysql-bin.xxxx 主从复制、数据恢复
从库同步 Relay Log 从库中继日志
从库执行 Buffer Pool / Redo Log / Binlog 与主库相同的执行流程

五、完整执行顺序图

客户端 → MySQL Server → 解析器 → 优化器 → 执行器
    ↓
InnoDB:
    1. 查找数据页(Buffer Pool / 数据文件)
    2. 加锁
    3. 修改内存数据
    4. 写 Undo Log
    5. 写 Redo Log Buffer
    ↓
事务提交:
    6. Redo Log prepare → 刷盘
    7. 写 Binlog Cache → 刷盘
    8. Redo Log ***mit
    ↓
主从复制:
    9. 主库 Binlog → 从库 I/O 线程 → Relay Log
    10. 从库 SQL 线程执行 Relay Log

=========================================================================

MySQL 中 Buffer Pool、Undo Log、Redo Log、Binlog、Relay Log 的作用和记录内容

1. Buffer Pool

  • 作用:InnoDB 的内存缓存区,用于缓存数据页索引页,减少磁盘 I/O。
  • 记录内容
    • 已读取的数据页(例如表数据、索引数据)
    • 修改后的数据页(脏页,等待刷盘)
  • 举例
    当你执行 SELECT * FROM user WHERE id=1 时,InnoDB 会先从 Buffer Pool 查找数据页,如果没有则从磁盘读取并缓存到 Buffer Pool,下次查询同样数据时直接从内存读取。

2. Undo Log

  • 作用回滚日志,用于事务回滚和 MV***(多版本并发控制)。
  • 记录内容
    • 修改前的旧数据(逻辑记录)
  • 举例
    执行 UPDATE user SET age=30 WHERE id=1 时,Undo Log 会记录 id=1 的原始 age=25。如果事务回滚,就用 Undo Log 恢复成 age=25

3. Redo Log

  • 作用重做日志,保证事务的持久性(崩溃恢复)。
  • 记录内容
    • 数据页的物理修改(页号、偏移量、修改内容)
  • 举例
    执行 UPDATE user SET age=30 WHERE id=1 时,Redo Log 会记录该数据页的物理变化,即“第 X 页的某个偏移位置改为 30”。即使 MySQL 崩溃,重启后也能用 Redo Log 恢复到事务提交后的状态。

4. Binlog

  • 作用二进制日志,用于主从复制、数据恢复。
  • 记录内容
    • SQL 语句或行变更事件(逻辑记录)
  • 举例
    执行 UPDATE user SET age=30 WHERE id=1 后,Binlog 会记录这条更新语句或对应的行变更事件,主库会将 Binlog 发送给从库,从库执行同样的更新,实现数据同步。

5. Relay Log

  • 作用中继日志,用于 MySQL 主从复制的从库端。
  • 记录内容
    • 从主库接收到的 Binlog 内容
  • 举例
    从库接收到主库的 Binlog(例如 UPDATE user SET age=30 WHERE id=1),会先写入 Relay Log,然后由 SQL 线程读取 Relay Log 并在从库执行更新。
组件名称 作用 记录内容 举例说明
Buffer Pool 缓存数据页和索引页,减少磁盘 I/O 已读取的数据页、修改后的脏页 查询 id=1 时,数据页先从 Buffer Pool 读取
Undo Log 回滚事务、实现 MV*** 修改前的旧数据(逻辑记录) 更新 age=30 时记录原值 age=25
Redo Log 崩溃恢复,保证持久性 数据页的物理修改 记录“第 X 页某偏移改为 30”
Binlog 主从复制、数据恢复 SQL 语句或行变更事件 记录 UPDATE user SET age=30 WHERE id=1
Relay Log 从库执行主库变更 主库 Binlog 内容 从库接收 Binlog 写入 Relay Log 再执行

Redo LogBinlog

1. 记录内容的区别

  • Redo Log

    • 记录的是物理层面的数据页修改(页号、偏移量、修改的字节内容)
    • 属于 InnoDB 引擎专用,只描述“数据页如何被改动”
    • 不能直接用来还原 SQL 语句,只能用来恢复数据页到某个状态
    • 例子
      页号=1234, 偏移=56, 原值=25, 新值=30 表示某个数据页的某个位置从 25 改成了 30。
  • Binlog

    • 记录的是逻辑层面的变更(SQL 语句或行变更事件)
    • 属于 MySQL Server 层,所有存储引擎都可以使用
    • 可以用来重放 SQL,实现主从复制或数据恢复
    • 例子
      UPDATE user SET age=30 WHERE id=1; 或者记录成行事件:id=1, age=30

2. 作用的区别

  • Redo Log:保证事务的持久性(崩溃恢复),让已提交事务在宕机后仍能恢复。
  • Binlog:用于数据复制归档,可以在不同 MySQL 实例之间同步数据,也可以用来做时间点恢复。

3. 存储方式的区别

特性 Redo Log Binlog
层级 InnoDB 引擎层 MySQL Server 层
内容类型 物理日志(页修改) 逻辑日志(SQL 或行事件)
用途 崩溃恢复 主从复制、数据恢复
是否循环写 是(固定大小循环写) 否(追加写,文件滚动)
是否所有引擎可用 否(仅 InnoDB) 是(所有引擎)

总结
Redo Log“怎么改数据页”Binlog“改了什么数据”
它们配合使用才能实现 事务的持久性数据的可复制性

转载请说明出处内容投诉
CSS教程网 » MySQL 更新(UPDATE)语句的执行流程,包括 存储引擎内部的文件写入 和 主从复制的同步过程

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买