MySQL之update语句执行流程解读

 更新时间:2026年05月02日 14:49:51   作者:北绿蚁  
文章详细描述了MySQL中`update`语句的执行流程,从BufferPool中查找数据到磁盘刷新脏页的全过程,涉及BufferPool、undolog、redolog、binlog、MDL锁等多个组件

图1 update语句执行流程

从 Buffer Pool(内存中) 中查看是否有这条数据,没有就从磁盘中加载到缓冲池,然后对这行记录加独占锁;

把更新行记录的旧值写入 undo log(以便回滚);

更新 Buffer Pool 中的数据(成脏数据);

执行器把对数据的修改情况写入 redo log 中(内存中) ;

准备提交事务时(prepare 阶段),按策略把 redo log 刷到 redo log 文件(磁盘中);

执行器生成这次更新的 binlog,再按策略刷到 binlog 文件(磁盘中);

执行器调用引擎的提交事务接口,完成最终的事务提交。(此时会把本次更新对应的 binlog 文件名称和这次更新的 binlog 文件里的位置,写入到 redo log 文件中,同时在 redo log 文件里写入一个 commit 标记)

如果触发刷新脏页的操作,则将内存更新后的脏数据刷回磁盘。

图2 update语句执行流程框架图

首先客户端通过 tcp/ip 发送一条 sql 语句到 server 层的 SQL interface;

SQL interface 接到该请求后,先对该条语句进行解析,验证权限是否匹配;

验证通过以后,分析器会对该语句分析,是否语法有错误等;

接下来是优化器器生成相应的执行计划,选择最优的执行计划;

之后会是执行器根据执行计划执行这条语句。

  • 在这一步会去 open table,如果该 table 上有 MDL 则等待。
  • 如果没有,则加在该表上加短暂的 MDL(S)。
  • (如果 opend_table 太大,表明 open_table_cache 太小。需要不停的去打开 frm 文件);

进入到引擎层,首先会去 innodb_buffer_pool 里的 data dictionary (元数据信息) 得到表信息;

通过元数据信息,去 lock info 里查出是否会有相关的锁信息,并把这条 update 语句需要的锁信息写入到 lock info 里(锁这里还有待补充);

然后涉及到的老数据通过快照的方式存储到 innodb_buffer_pool 里的 undo page 里,并且记录 undo log 修改的 redo(如果 data page 里有就直接载入到 undo page 里,如果没有,则需要去磁盘里取出相应 page 的数据,载入到 undo page 里);

在 innodb_buffer_pool 的 data page 做 update 操作。并把操作的物理数据页修改记录到 redo log buffer 里,由于 update 这个事务会涉及到多个页面的修改,所以 redo log buffer 里会记录多条页面的修改信息。因为 group commit 的原因,这次事务所产生的 redo log buffer 可能会跟随其它事务一同 flush 并且 sync 到磁盘上;

同时修改的信息,会按照 event 的格式,记录到 binlog_cache 中。(这里注意 binlog_cache_size 是 transaction 级别的,不是 session 级别的参数,一旦 commit 之后,dump 线程会从 binlog_cache 里把 event 主动发送给 slave 的 I/O 线程);

之后把这条 sql,需要在二级索引上做的修改,写入到 change buffer page,等到下次有其他 sql 需要读取该二级索引时,再去与二级索引做 merge 。

(随机I/O变为顺序I/O,但是由于现在的磁盘都是SSD,所以对于寻址来说,随机I/O和顺序I/O差距不大);

此时 update 语句已经完成,需要 commit 或者 rollback。这里讨论 commit 的情况;

  • commit 操作,由于存储引擎层与 server 层之间采用的是内部 XA (保证两个事务的一致性,这里主要保证 redo log 和 binlog 的原子性),所以提交分为 prepare 阶段与 commit 阶段;
  • prepare 阶段,将事务的 xid 写入,将 binlog_cache 里的进行 flush 以及 sync 操作(大事务的话这步非常耗时);
  • commit 阶段,由于之前该事务产生的 redo log 已经 sync 到磁盘了。所以这步只是在 redo log 里标记 commit;

当 binlog 和 redo log 都已经落盘以后,如果触发了刷新脏页的操作,先把该脏页复制到 doublewrite buffer 里,把 doublewrite buffer 里的刷新到共享表空间,然后才是通过 page cleaner 线程把脏页写入到磁盘中。

其实在实现上5是调用了6的过程了的,所以是一回事。MySQL server 层和InnoDB层都保存了表结构,所以有书上描述时会拆开说。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Windows环境下重置mysql密码操作命令

    Windows环境下重置mysql密码操作命令

    Windows XP系统、xampp集成环境如何重置mysql密码,接下来为大家详细介绍下,感兴趣的各位可以参考下哈,希望可以帮助到你们
    2013-03-03
  • MySQL表的操作之创建查看删除和修改

    MySQL表的操作之创建查看删除和修改

    这篇文章主要给大家介绍了关于MySQL表的操作之创建查看删除和修改的相关资料,MySQL是最常用的数据库,在数据库操作中基本都是增删改查操作,简称CRUD,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • mysql批量更新多条记录的同一个字段为不同值的方法

    mysql批量更新多条记录的同一个字段为不同值的方法

    最近在工作的时候突然想到了一个问题,就是mysql如何才能实现批量更新多条记录的同一个字段为不同值,于是就动手实践起来了,发现其中的学问还是挺多的,所以想着就总结下来分享给大家,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • 9种 MySQL数据库优化的技巧

    9种 MySQL数据库优化的技巧

    这篇文章小编主要给大家介绍的是 MySQL数据库优化的正确姿势,九种方法呢!!!需要的小伙伴赶快收藏起来吧
    2021-09-09
  • MySQL批量更新数据的多种方法与最佳实践

    MySQL批量更新数据的多种方法与最佳实践

    在数据库操作中,批量更新数据是常见的需求场景,无论是数据迁移、数据修正还是批量处理业务逻辑,本文将深入探讨MySQL中批量更新数据的多种方法及其适用场景,需要的朋友可以参考下
    2026-01-01
  • windows系统mysql压缩包版本安装过程

    windows系统mysql压缩包版本安装过程

    这篇文章主要介绍了windows系统mysql压缩包版本安装过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 关于数据库中的查询优化

    关于数据库中的查询优化

    这篇文章主要介绍了关于数据库中的查询优化,对于大型的应用系统,数据动辄上百万,就需要了解DBMS对查询语句的处理过程和优化算法,更好的利用其优化算法,以提高系统的性能,需要的朋友可以参考下
    2023-07-07
  • 数据库连接池以及sequelize实现增删改查等操作指南

    数据库连接池以及sequelize实现增删改查等操作指南

    Sequelize的连接需要传入参数,并且可以配置开启线程池、读写分库等操作,下面这篇文章主要给大家介绍了关于数据库连接池以及sequelize实现增删改查等操作的相关资料,需要的朋友可以参考下
    2022-08-08
  • sql模式设置引起的问题解决办法

    sql模式设置引起的问题解决办法

    这篇文章主要介绍了sql模式设置引起的问题解决办法,文章围绕主题展开详细内容,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • MySql 5.6.14 winx64配置方法(免安装版)

    MySql 5.6.14 winx64配置方法(免安装版)

    这篇文章主要介绍了MySql 5.6.14 winx64配置方法(免安装版)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-08-08

最新评论