图1 update语句执行流程

  1. 从 Buffer Pool(内存中) 中查看是否有这条数据,没有就从磁盘中加载到缓冲池,然后对这行记录加独占锁;
  2. 把更新行记录的旧值写入 undo log(以便回滚);
  3. 更新 Buffer Pool 中的数据(成脏数据);
  4. 执行器把对数据的修改情况写入 redo log 中(内存中) ;
  5. 准备提交事务时(prepare 阶段),按策略把 redo log 刷到 redo log 文件(磁盘中);
  6. 执行器生成这次更新的 binlog,再按策略刷到 binlog 文件(磁盘中);
  7. 执行器调用引擎的提交事务接口,完成最终的事务提交。(此时会把本次更新对应的 binlog 文件名称和这次更新的 binlog 文件里的位置,写入到 redo log 文件中,同时在 redo log 文件里写入一个 commit 标记)
  8. 如果触发刷新脏页的操作,则将内存更新后的脏数据刷回磁盘。

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

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

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

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

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

  5. 之后会是执行器根据执行计划执行这条语句。
    在这一步会去 open table,如果该 table 上有 MDL 则等待。
    如果没有,则加在该表上加短暂的 MDL(S)。
    (如果 opend_table 太大,表明 open_table_cache 太小。需要不停的去打开 frm 文件);

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

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

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

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

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

  11. 之后把这条 sql,需要在二级索引上做的修改,写入到 change buffer page,等到下次有其他 sql 需要读取该二级索引时,再去与二级索引做 merge 。
    (随机I/O变为顺序I/O,但是由于现在的磁盘都是SSD,所以对于寻址来说,随机I/O和顺序I/O差距不大);

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

  13. commit 操作,由于存储引擎层与 server 层之间采用的是内部 XA (保证两个事务的一致性,这里主要保证 redo log 和 binlog 的原子性),所以提交分为 prepare 阶段与 commit 阶段;

  14. prepare 阶段,将事务的 xid 写入,将 binlog_cache 里的进行 flush 以及 sync 操作(大事务的话这步非常耗时);

  15. commit 阶段,由于之前该事务产生的 redo log 已经 sync 到磁盘了。所以这步只是在 redo log 里标记 commit;

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

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

参考资料

[1]《MySQL实战45讲》
[2] MySQL技术内幕 InnoDB存储引擎 第2版

MySQL——update 语句执行流程相关推荐

  1. MYSQL(二):update语句执行的秘密

    MYSQL(二):update语句执行的秘密 在上一篇博客mysql查询里,已经大致讲了MySQL的一些组件,和MySQL的查询语句是如何返回结果的,现在再来研究一下MySQL是如何进行更新操作的,虽 ...

  2. 详解MySQL的逻辑架构和SQL语句执行流程

    文章目录 1. 逻辑架构 1.1 连接层 1.2 服务层 1.3 引擎层 1.3.1 InnoDB 存储引擎 1.3.2 MyISAM 存储引擎 1.3.3 其他存储引擎 1.4 存储层 3. SQL ...

  3. 一文搞懂select语句在MySQL中的执行流程!

    MySQL作为互联网行业使用最多的关系型数据库之一,与其免费.开源的特性是密不可分的.然而,很多小伙伴工作了很多年,只知道使用MySQL进行CRUD操作,这也导致很多小伙伴工作多年后,想跳槽进入大厂, ...

  4. mysql 查询语句执行顺序_MySQL 查询语句执行过程

    MySQL 查询语句执行过程 Mysql分为server层和存储引擎两部分,或许可以再加一层连接层 连接层(器) Mysql使用的是典型的C/S架构.连接器通过典型的TCP握手完成连接. 需要注的是, ...

  5. MySQL UPDATE 语句一个“经典”的坑

    转载自  MySQL UPDATE 语句一个"经典"的坑 来源:ju.outofmemory.cn/entry/336774 有问题的SQL语句 why? 倒回去再重试验一把 最近 ...

  6. MySQL update正在执行中突然断电,数据是否更改成功?

    今天有个朋友突然问到我这个问题,当我们的update语句执行过程中,服务器突然断电了会发生什么?其实这个问题主要在于对mysql update生命周期的理解,以及了解mysql 的redolog和bi ...

  7. 瞎说系列——Mysql update的执行过程

    要了解mysql update语句的执行过程,首先要了解一下mysql是如何进行数据的操作的. 首先,数据库中的数据存在哪?肯定是文件系统,磁盘上对吧.那么思考一下,每次查询都从磁盘上去查找吗? 答案 ...

  8. Mysql SQL语句执行更新或者插入添加条件判断

    Mysql SQL语句执行更新或者插入添加条件判断 – 更新操作 – INSERT INTO materials (ID,Name,Remaining,Total) VALUES (1,'SolidW ...

  9. Oracle SQL语句执行流程与顺序原理详解

    以前读的文章,保存到本地了,忘记来源了,分享一下,本地存着怕丢了 Oracle SQL语句执行流程与顺序原理详解 第一步:客户端把语句发给服务器端执行 当我们在客户端执行SQL语句时,客户端会把这条S ...

最新文章

  1. 多项目管理,研发管理,敏捷开发软件
  2. linux wifi修改频率,Linux Custom CRDA WiFi regulatory.bin和40MHz BW 5GHz频...
  3. java网关限流_网关限流使用
  4. C语言学习之求∑k(k=100)+∑K*k(k=50)+∑1/k(k=10)
  5. 【转】JNI学习积累之一 ---- 常用函数大全
  6. 对视频中的特征颜色物体(青色水杯)进行跟踪
  7. java 判断请求为 ajax请求_Java后台判断ajax请求及处理过程详解
  8. SpecFlow的力量
  9. Java21天打卡day18--继承
  10. 一行代码进行闰年的判断
  11. Atitit 数据类型体系图 目录 1. 系统常用的数据类型 1 2. H5 form表单新数据类型 2 2.1. TML5 新的 Input 类型 2 2.2. HTML5 的新的表单元素: 2
  12. UTM坐标转GPS方法分享
  13. word文档中实现目录索引中标题加粗,前导符和页码不加粗
  14. 【LInux入门手册】目录结构 常用指令与操作 vim与tmux
  15. 启动docker时映射到宿主机时出现 /usr/bin/docker-current: Error response from daemon: driver failed……的解决方案
  16. java Excel导出功能之 固定列表格
  17. 学习线性代数-行列式 笔记(一)
  18. 基于TCP的socket详解(Linux系统)
  19. Robotstudio 获取机器人D-H参数
  20. arduino中的serial .available()和serial.read()是区别

热门文章

  1. 安泰测试Agitek-TH2826型 LCR数字电桥
  2. 占豪的投资博客--揭穿美借助“货币战争”操纵世界的巨大阴谋(一)
  3. http://www.floorplanner.com/
  4. 五个整蛊小程序,被打了别说在我这里看的!
  5. mysql在window机器下的双机备份
  6. 装饰者模式(带例子)
  7. Hbase单机安装教程
  8. 阿里正式推出短视频独立app对标抖音?商品推广才是重点!
  9. 发现wp7开发安全策略能够突破
  10. Unreal Engine 4 系列教程 Part 3:材质教程