当前位置: 首页 > news >正文

一条sql语句在MySQL的执行流程

一条sql语句在MySQL的执行流程

Server层和存储引擎层

Server层

  • 连接器: 身份认证和权限相关(登录 MySQL 的时候)。
  • 查询缓存: 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。
  • 分析器: 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。
  • 优化器: 按照 MySQL 认为最优的方案去执行。
  • 执行器: 执行语句,然后从存储引擎返回数据。

分析器:
第一步,词法分析,一条 SQL 语句有多个字符串组成,首先要提取关键字,比如 select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。

第二步,语法分析,主要就是判断你输入的 sql 是否正确,是否符合 MySQL 的语法。

优化器:
优化器的作用就是它认为的最优的执行方案去执行(有时候可能也不是最优,这篇文章涉及对这部分知识的深入讲解),比如多个索引的时候该如何选择索引,多表查询的时候如何选择关联顺序等。

可以说,经过了优化器之后可以说这个语句具体该如何执行就已经定下来。
执行器:

当选择了执行方案后,MySQL 就准备开始执行了,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果。

图片

存储引擎层
主要负责数据的存储和读取,采用可以替换的插件式架构,支持 InnoDB、MyISAM、Memory 等多个存储引擎,其中 InnoDB 引擎有自有的日志模块 redolog 模块。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始就被当做默认存储引擎了。

1、一条查询语句

  • 连接器先检查权限,查询缓存,如果有缓存就直接缓存,没有缓存下一步;
  • 分析器进行词法分析,提取select 表名,条件等。然后判断语法是否有误正常就下一步
  • 优化器确定执行方案,查询可能有两种执行方案
a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是 18。
b.先找出学生中年龄 18 岁的学生,然后再查询姓名为“张三”的学生。

选择一个他认为效率最好的执行

  • 执行器:进行权限校验,有权限就调用数据库引擎

2、一条更新语句

既然是更新,肯定要记录日志。mysql自带的binlog(归档日志),InnoDB自带的redo log(重做日志)

update tb_student A set A.age='19' where A.name=' 张三 ';
  • 连接器检查权限
  • 先查张三这条数据,有缓存就清除
  • 分析器分析语句 把年龄改为19,调用引擎API接口,写入这行数据;InnoDB引擎把数据保存在内存中,同时记录redo log,此时redo log进入prepare状态,然后告诉执行器,执行完成了,随时可以提交事务
  • 执行器收到通知后记录binlog,并把binlog写入磁盘;
  • 然后调用引擎接口,redo log为提交状态
  • 更新完成

这里肯定有人会问,为什么要用两个日志模块,用一个日志模块不行吗?

这是因为最开始 MySQL 并没与 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) ,MySQL 自带的引擎是 MyISAM,但是我们知道 redo log 是 InnoDB 引擎特有的,其他存储引擎都没有,这就导致会没有 crash-safe 的能力(crash-safe 的能力即使数据库发生异常重启,之前提交的记录都不会丢失),binlog 日志只能用来归档。

并不是说只用一个日志模块不可以,只是 InnoDB 引擎就是通过 redo log 来支持事务的。那么,又会有同学问,我用两个日志模块,但是不要这么复杂行不行,为什么 redo log 要引入 prepare 预提交状态?这里我们用反证法来说明下为什么要这么做?

  • 先写 redo log 直接提交,然后写 binlog,假设写完 redo log 后,机器挂了,binlog 日志没有被写入,那么机器重启后,这台机器会通过 redo log 恢复数据,但是这个时候 bingog 并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。

  • 先写 binlog,然后写 redo log,假设写完了 binlog,机器异常重启了,由于没有 redo log,本机是无法恢复这一条记录的,但是 binlog 又有记录,那么和上面同样的道理,就会产生数据不一致的情况。

如果采用 redo log 两阶段提交的方式就不一样了,写完 binglog 后,然后再提交 redo log 就会防止出现上述的问题,从而保证了数据的一致性。那么问题来了,有没有一个极端的情况呢?假设 redo log 处于预提交状态,binglog 也已经写完了,这个时候发生了异常重启会怎么样呢? 这个就要依赖于 MySQL 的处理机制了,MySQL 的处理过程如下:

  • 判断 redo log 是否完整,如果判断是完整的,就立即提交。
  • 如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如果完整就提交 redo log, 不完整就回滚事务。

这样就解决了数据一致性的问题。

相关文章:

  • 当遇到听不了的歌,Python程序员都是这么做的...
  • leetcode-289:生命游戏
  • C语言中的结构体应用详解及注意事项
  • 【2022】Elasticsearch-7.17.6集群部署
  • 计算器——位运算(c语言)
  • Maven 基础 5 第一个Maven 项目(IDEA 生成)
  • TypeScript算法题实战——哈希表篇
  • 嵌入式分享合集71
  • 又一巅峰神作 14年工作经验大佬手写“微服务项目下高并发的流量治理”,太牛了
  • 谷歌翻译失败解决方案
  • 网络安全面试题目及详解
  • 【初阶与进阶C++详解】第二十三篇:异常(异常抛出+异常捕获+异常优缺点)
  • 第二弹:看了图像分割一系列Unet、DeepLabv3+改进期刊论文,总结改进创新的一些相同点
  • HTML期末大作业 使用HTML+CSS制作科技文化主题网站(航天之路)
  • ElasticSearch_04_批量处理命令mget和bulk的使用
  • Docker入门(二) - Dockerfile
  • es6--symbol
  • mysql中InnoDB引擎中页的概念
  • nginx 配置多 域名 + 多 https
  • Python_网络编程
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Vue UI框架库开发介绍
  • Vue.js-Day01
  • 从零搭建Koa2 Server
  • 讲清楚之javascript作用域
  • 蓝海存储开关机注意事项总结
  • 模型微调
  • 排序(1):冒泡排序
  • 前端之React实战:创建跨平台的项目架构
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 优秀架构师必须掌握的架构思维
  • 源码安装memcached和php memcache扩展
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #git 撤消对文件的更改
  • $.ajax中的eval及dataType
  • $refs 、$nextTic、动态组件、name的使用
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (层次遍历)104. 二叉树的最大深度
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)ssm高校实验室 毕业设计 800008
  • (六)Hibernate的二级缓存
  • (一)kafka实战——kafka源码编译启动
  • (转)平衡树
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .NET NPOI导出Excel详解
  • .NET 表达式计算:Expression Evaluator
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • @RequestMapping处理请求异常
  • @RequestMapping-占位符映射
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)
  • [.net] 如何在mail的加入正文显示图片
  • [2024] 十大免费电脑数据恢复软件——轻松恢复电脑上已删除文件