前言
通过本文主要了解Sql执行流程,包括两个问题:
先看第一个问题,这里做个简单描述 ,因为我们着重还是看Update
MySQL执行一条Select语句是怎么运行的?
这个问题大家在面试的时候大家都背过类似的题,而且网上也有很多答案,这里分享一个大致流程介绍,关于下图的介绍来自这里 执行一条 select 语句,期间发生了什么?。
- 连接器:建立连接,管理连接、校验用户身份;
- 查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL 8.0 已删除该模块;
- 解析 SQL,通过解析器对 SQL 查询语句进行词法分析、语法分析,然后构建语法树,方便后续模块读取表名、字段、语句类型;
- 执行 SQL:执行 SQL 共有三个阶段:
- 预处理阶段:检查表或字段是否存在;将 select * 中的 * 符号扩展为表上的所有列。
- 优化阶段:基于查询成本的考虑, 选择查询成本最小的执行计划;
- 执行阶段:根据执行计划执行 SQL 查询语句,从存储引擎读取记录,返回给客户端
相对于Select,内容更多和更复杂的是Update语句的执行,接下来我们讲展开细讲,再看本文之前可以先看看之前的分享,这两篇文章对Double Write和Buffer Pool有做详细的介绍:
MySQL的Double Write如何保证可靠性?
InnoDB的Buffer Pool是如何管理数据页的?
当然最好也了解下 redolog、undolog、binlog的相关知识点,这块知识我们会在后续继续分享!
Update执行逻辑
先把我画的图看完,图中步骤比较多,需要花点时间看,你想我画这个肯定花了更长时间,如果觉得还不错的话,谢谢点赞收藏下,不足的话大家指正下!
执行流程图
整个流程的架构很清晰:Client客户端、Server层、InnoDB引擎层、磁盘,这里就不对每个组件的具体功能和细节处理做更详细的解释了,文章主要是帮我们把流程理清楚!
核心组成部分
当然这里也涉及到几个核心:Buffer Pool、Double Write、Redo Log、Undo Log、BinLog、WAL
Buffer Pool和Double Write可以参考我之前的文章,在开头就有分享原文链接,我们来看以下问题!
Redo Log、Undo Log、BinLog分别存的什么内容,分别是做什么用的?
WAL是什么,哪里用到了它?
WAL全称为Write-Ahead Logging,预写日志系统。主要写undo log、redo log、binlog这些用到了。
真正使用WAL的原因是:磁盘的写操作是随机IO,比较耗性能,所以如果把每一次的更新操作都先写入log中,那么就成了顺序写操作,实际更新操作由后台线程再根据log异步写入
UndoLog会存储在哪些地方?
我们从图中也可以清晰的知道UndoLog在两个地方:Buffer Pool中的undo page页,和磁盘中的表共享空间的Undo log
详解执行流程
看完执行流程图大家都有个大概印象了,我们分三个部分进行更具体的文字化描述,一起来看看吧!
Client客户端:
Server层:
Server层和存储引擎之间怎么通信的呢?
到这里用户发送的一个SQL已经经过各种验证、分析、优化到了执行阶段,那么接下来就是执行器怎么和InnoDB存储引擎打交道了。
对于Server层来说,它是不知道存储引擎的实现细节的,而是通过定义的API接口和存储引擎通信。可以理解为存储引擎是一个类,然后每个实例(InnoDB)都通过一个特殊的处理程序接口与MySQL服务器通信。
InnoDB引擎层:
现在已经到了引擎层了,存储引擎主要负责数据的存储和读取
什么是二阶段提交?
二阶段提交,顾名思义,会包含 2 个阶段:
prepare 阶段,协调器会询问所有执行器,是否可以提交事务
commit 阶段,协调器会通知执行器进行提交操作
update的执行阶段也用到了,比如:
- prepare 阶段:将 redo log 对应的事务状态设置为 prepare,然后将 redo log 刷新到硬盘;
- commit 阶段:将 binlog 刷新到磁盘,接着调用引擎的提交事务接口,将 redo log 状态设置为 commit(将事务设置为 commit 状态后,刷入到磁盘 redo log 文件)
总结
今天的分享就到这了,我们平时一条Update语句其实内部会经历很多流程,语句解析、日志WAL,Buffer Pool等。通过今天这篇文章的分享相信大家对流程已经很清晰了,后续将继续带来Redo Log、UndoLog等内容,敬请期待!
👨👩 你好,朋友,希望本文对你有帮助~🌐
欢迎点赞 👍、收藏 💙、关注 💡 三连支持一下~🎈
我会继续输出更高质量文章进行分享~🙇💻