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的数据安全。

相关推荐
ss2735 小时前
为什么PostgreSQL适合AI场景?
数据库·人工智能·postgresql
瑞克-桑切斯5 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
z06.6 小时前
MySQL索引
数据库·mysql
考虑考虑6 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
云祺vinchin6 小时前
中小企业备份软件选型从恢复需求到总体成本评估
数据库·数据备份·中小企业备份·容灾备份软件
Zenova EdgeOS7 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
KKKlucifer7 小时前
国内数据安全服务的产品智能化转型:大模型赋能下的技术能力重构分析
大数据·数据库·重构
字节跳动开源8 小时前
OpenViking 上线原生 3D 内容理解模型
数据库·开源
CCIE-Yasuo10 小时前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
这个DBA有点耶10 小时前
内核级AI与多模融合:AI数据库在海外场景的落地要点
数据库·人工智能·架构