MySQL更新语句执行全流程:从Buffer Pool修改到二阶段提交

文章目录

  • 前言
  • 一条SQL更新语句是如何执行的?
    • [第一阶段:Server 层的准备与查找阶段](#第一阶段:Server 层的准备与查找阶段)
      • [1. 连接器与分析器:](#1. 连接器与分析器:)
      • [2. 优化器与执行器:](#2. 优化器与执行器:)
    • [第二阶段:InnoDB 引擎的内存与日志操作(真正开始改数据)](#第二阶段:InnoDB 引擎的内存与日志操作(真正开始改数据))
      • [1. 引擎搜寻与加载数据(Buffer Pool 机制):](#1. 引擎搜寻与加载数据(Buffer Pool 机制):)
      • [2. 记录回滚日志(undo log):](#2. 记录回滚日志(undo log):)
      • [3. 在内存中更新数据:](#3. 在内存中更新数据:)
    • 第三阶段:核心"二阶段提交"与日志落盘
      • [1. 写入 redo log --- Prepare 阶段(第一阶段)](#1. 写入 redo log — Prepare 阶段(第一阶段))
      • [2. 写入 binlog --- 提交阶段(第二阶段 A)](#2. 写入 binlog — 提交阶段(第二阶段 A))
      • [3. 修改 redo log 状态 --- Commit 阶段(第二阶段 B)](#3. 修改 redo log 状态 — Commit 阶段(第二阶段 B))
  • 结语

前言

更新语句的执行远比查询复杂。它不仅要在内存中修改数据,还要在崩溃时保证数据不丢、在主从之间保持一致。理解这条涉及undo log、redo log与binlog的写入链路,是你掌握MySQL事务与数据安全机制的必经之路。

一条SQL更新语句是如何执行的?

接下来我将以UPDATE user SET name = '李四' WHERE id = 10;这行SQL更新语句来解释执行过程

第一阶段:Server 层的准备与查找阶段

1. 连接器与分析器:

  • 客户端发送更新语句。连接器首先进行权限校验。
  • 分析器进行词法和语法分析,识别出这是一条 UPDATE 语句,要更新 user 表中 id = 10 的行。

2. 优化器与执行器:

  • 优化器决定使用 id 的主键索引,并生成执行计划。
  • 执行器负责指挥存储引擎。但在修改数据之前,执行器必须先拿到这行数据。
  • 执行器调用 InnoDB 引擎接口:"帮我把 id = 10 这一行的数据取出来"。

第二阶段:InnoDB 引擎的内存与日志操作(真正开始改数据)

1. 引擎搜寻与加载数据(Buffer Pool 机制):

  • InnoDB 收到请求后,先去内存的 Buffer Pool(缓冲池) 中查找是否存在 id = 10 所在的数据页。
  • 如果在内存中,直接读出准备修改;如果不在内存中,引擎会先从磁盘将该数据页读入到 Buffer Pool 中。

2. 记录回滚日志(undo log):

  • 在内存中准备修改数据之前,InnoDB 会先将这一行原先的值(比如 name = '张三')记录到 undo log 中。
  • 底层作用:undo log 是为了实现事务的原子性(A)。如果后续事务因为某种原因回滚(Rollback),或者程序崩溃,数据库需要利用 undo log 把数据恢复成原本的模样。

3. 在内存中更新数据:

  • 记录完 undo log 后,InnoDB 引擎正式在内存(Buffer Pool)中执行修改,将 name 的值改为 '李四'
  • 注意:此时,磁盘上的数据文件还没有被修改,内存中的这个数据页与磁盘上的不一致,变成了"脏页(Dirty Page)"。MySQL 并不是每执行一条更新就立刻写一次磁盘,因为随机磁盘 I/O 极其缓慢,它会等待后台线程异步将脏页刷新(Flush)到磁盘。

第三阶段:核心"二阶段提交"与日志落盘

为了防止由于内存更新了、磁盘没更新时突然断电导致数据丢失,以及为了保证主从库数据的一致性,接下来的日志写入将严格遵循二阶段提交(Two-Phase Commit):

1. 写入 redo log --- Prepare 阶段(第一阶段)

  • InnoDB 引擎将"在某个数据页的某个偏移量上把 name 改为了李四"这一物理变动记录到 redo log(重做日志)中。
  • 此时,将该事务在 redo log 中的状态标记为 prepare(准备阶段)。
  • 接着,把 redo log 对应的内存数据强行刷新到磁盘上(由 innodb_flush_log_at_trx_commit 参数控制)。
  • 引擎向执行器汇报:"我这边已经写好物理日志并进入准备状态了,你可以写 binlog 了"。

2. 写入 binlog --- 提交阶段(第二阶段 A)

  • 执行器收到引擎的通知后,开始生成这一条操作的 binlog(逻辑日志,记录的是具体的 SQL 语句或行变化数据,如"将 id=10 的 name 改为李四")。
  • 执行器将 binlog 写入到 Server 层的 binlog 文件中,并强行刷新到磁盘(由 sync_binlog 参数控制)。

3. 修改 redo log 状态 --- Commit 阶段(第二阶段 B)

  • binlog 写入成功后,执行器调用引擎的事务提交接口。
  • InnoDB 引擎把刚刚在 redo log 中该事务的状态从 prepare 改为 commit(提交状态)
  • 至此,整个更新事务宣告成功结束,执行器向客户端返回"更新成功"。

结语

每一次UPDATE背后,都是内存、磁盘与日志的精密协作。undo log守护回滚,redo log抵御崩溃,binlog维系主从,二阶段提交则将三者拧成一股绳。懂了这条链路,你才真正懂了MySQL的数据安全。

相关推荐
故乡dee云2 小时前
AWS 产品太多不会选?按“网站、数据库、文件、日志”4 类需求快速匹配
数据库·云计算·aws
曹牧3 小时前
C#:问号
前端·数据库·c#
奇树谦4 小时前
《现代 Key-Value 数据库原理:从 B+Tree 到 LSM Tree》-第五篇:现代数据库横向对比
数据库·lsm-tree
李白客4 小时前
分布式集群与数据库产业:从单机到集群的架构跃迁与市场重构
数据库·分布式·架构
福大大架构师每日一题4 小时前
Redis 8.10.0 正式发布:紧凑哈希、批量导入、备份恢复、流与时序能力全面升级
数据库·redis·哈希算法
雨晨源码(同名B站)5 小时前
基于深度学习YoloV11农业病害虫害检测系统 智慧农业信息化综合管理平台 (附源码+lw文档+ppt)
数据库·人工智能·深度学习·yolo·信息可视化
DBA小马哥6 小时前
向量数据库入门到进阶:Embedding、ANN算法与RAG落地的关键术语
数据库·算法·embedding
云和数据.ChenGuang6 小时前
fastapi项目拆分实战数据模型
java·服务器·数据库·人工智能·深度学习·fastapi·强化学习
祈禾6 小时前
Redis三大特殊数据类型
运维·服务器·数据库·redis·笔记·缓存
东方护航数据恢复(深圳)6 小时前
MySQL_Oracle数据库崩溃修复全攻略_东方护航数据恢复深圳店
数据库·mysql·oracle