一条 SQL 语句是如何执行的

SQL查询语句

select * from user where ID=10;

MySQL 的基本架构可以分为 Server 层和存储引擎两部分。Server 层又包含连接器、(查询缓存)、分析器、优化器和执行器。

连接器:连接器负责和客户端建立连接、获取权限、维持和管理连接。

查询缓存:建立连接后可以执行 SELECT 语句,执行逻辑来到第二步查询缓存。

MySQL 拿到查询请求后,会先到查询缓存中查看,是不是之前执行过的语句。查询缓存的存储形式是 key-value 形式,key是查询语句,value是查询结果。如果在缓存中则直接返回,不在缓存中则执行后续步骤,将结果放到缓存中。但不建议使用查询缓存,因为只要有对一个表的更新,这个表上的所有查询缓存都会被清空,因此很大的可能是把结果缓存起来之后,还没来的及用,就被清空了,利大于弊。MySQL8.0 彻底删除了查询缓存。

分析器:先进行词法分析在进行语法分析。

  • 词法分析:MySQl 要识别出你输入的这条语句里的字符串分别是什么,代表什么。通过 “select” 关键字识别这是一条查询语句,通过 “user” 识别成 “表名 user”。
  • 语法分析:语法分析器会根据 MySQL 的语法规则判断你输入的 SQL 语句是否符合 MySQL 的语法规范。

优化器:优化器负责当表里有多个索引的时候决定用哪一个,当语句中有多表关联时选择连接顺序

执行器:判断对要查询的表是否有执行查询的权限,没有返回权限错误,有权限则打开表,执行器根据表的引擎定义,去使用这个引擎提供的接口。

SQL 更新语句

update T set c=c+1 where ID=10;

查询语句走的流程更新语句也会走一遍,不再赘述。不同的是,更新语句执行的过程中会涉及两个重要的日志模块:redo log(重做日志)和 binlog(归档日志)

redo log

redo log 可以使 InnoDB保证即时数据库发生异常重启,之前的记录都不会丢失(crash-safe)

如果每次更新操作都立刻写入磁盘,然后磁盘找到数据进行修改整个过程 IO 成本、查找成本都很高,为了解决这个问题 MySQL 应用了 WAL(Write-Ahead Logging 写前日志)先写日志在写磁盘

具体来说,当有一条更新记录来的时候,InnoDB 会先把记录写到 redo log里,并更新内存,等到闲时再把操作写回磁盘。

redo log 是固定大小的。从头开始写,写到末尾就又从头开始写。

write pos:当前记录的位置,边写边后移,写到末尾则从头开始。

checkpoint:当前要擦除的位置,也是向后推并循环的。

write pos 和 checkpoint 之间空着的部分,可以用来记录新的操作,当 write pos 追上 checkpoint 重合时,这时就不能继续执行更新操作了,要停下来擦除一些记录,将 checkpoint 向后推。

binlog

redo log 是InnoDB 引擎特有的日志,binlog 是 MySQL 的日志,没有 crash-safe。

两种日志的不同点:

  1. redo log 是 InnoDB 引擎特有的,binlog 是 MySQL 的 Server 层实现的,所有的引擎都可以用。
  2. redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑如“给 ID=10 这一行的 c 字段加 1”。
  3. redo log 是循环写的,binlog 是追加写的,写满了不会覆盖,切换到下一个继续写。

update 语句的内部流程

update T set c=c+1 where ID=10;
  1. 执行器先找引擎取到 ID=10 这一行,ID是主键,引擎直接用搜索树找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则需要先从磁盘读入内存再返回给执行器。
  2. 执行器拿到这行数据后,执行修改操作,得到新的一行数据,再调用引擎接口写回这行数据。
  3. 引擎将这行数据更新到内存中,同时将这个更新操作记录到 redo log 中,此时 redo log 处于 prepare 状态,然后告知执行器,执行完了,可以随时提交事物。
  4. 执行器生成这个操作的 binlog,并把binlog写入磁盘。
  5. 执行器调用引擎接口提交事务,并把 redo log 改成 commit 状态,更新完成。

两阶段提交

假设要把c=0更新成c=1

  1. 先写 redo log 再写 binlog

    假设 redo log 写完了 binlog 还没写,这时候数据库挂了,重启后进行恢复,这时候通过redo log恢复后 c仍然是1。

    但binlog并没有写完就crash了,因此binlog里并没有这条语句,日后在用binlog进行恢复临时库时就会出现主从库不一致的现象。

  2. 先写binlog 再写 redo log

    如果在binlog写完之后crash,由于redo log还没写,崩溃恢复以后这个事务无效,所以这一行c的值是0。但是binlog里面已经记录了“把c从0改成1”这个日 志。所以,在之后用binlog来恢复的时候就多了一个事务出来,恢复出来的这一行c的值就是 1,与原库的值不同。

简单说,redo log和binlog都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保

持逻辑上的一致。

一条 SQL 语句是如何执行的的更多相关文章

  1. 一条SQL语句是如何执行的?--Mysql45讲笔记记录 打卡day1

    写在前面的话:回想以前上班的时候,空闲时间还是挺多的,但是都荒废了.如今找工作着实费劲了.但是这段时间在极客时间买了mysql45讲,就好像发现了新大陆一样,这是我认真做笔记的第一天,说实话第一讲我已 ...

  2. 《Mysql 一条 SQL 语句是如何执行的?》

    一:概述 - 首先需要认识一下 Mysql 整体的基础架构 -  二:Mysql 的分层 - MySQL 可以分为 Server 层和存储引擎层两部分 - Server 层 - Server 层包括连 ...

  3. 腾讯面试:一条SQL语句执行得很慢的原因有哪些?---不看后悔系列

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...

  4. 一条SQL语句执行得很慢的原因有哪些?

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你“输入URL回车之后,究竟发生了什么”一样,看看你能说出多少了. 之前腾讯面试的实话,也问到这 ...

  5. 一条SQL语句在MySQL中如何执行的

    本篇文章会分析一个 sql 语句在 MySQL 中的执行流程,包括 sql 的查询在 MySQL 内部会怎么流转,sql 语句的更新是怎么完成的. 在分析之前我会先带着你看看 MySQL 的基础架构, ...

  6. 一条SQL语句执行得很慢的原因有哪些?(转)

    一条 SQL 语句执行的很慢,那是每次执行都很慢呢?还是大多数情况下是正常的,偶尔出现很慢呢?所以我觉得,我们还得分以下两种情况来讨论. 1.大多数情况是正常的,只是偶尔会出现很慢的情况. 2.在数据 ...

  7. 一条SQL语句在MySQL中是如何执行的

    概览 本篇文章会分析下一个sql语句在mysql中的执行流程,包括sql的查询在mysql内部会怎么流转,sql语句的更新是怎么完成的. 一.mysql架构分析 mysql主要分为Server层和存储 ...

  8. 一条 SQL 语句在 MySQL 中如何执行的

    一 MySQL 基础架构分析 1.1 MySQL 基本架构概览 下图是 MySQL 的一个简要架构图,从下图你可以很清晰的看到用户的 SQL 语句在 MySQL 内部是如何执行的. 先简单介绍一下下图 ...

  9. 一条SQL语句执行得很慢的原因有哪些

    说实话,这个问题可以涉及到 MySQL 的很多核心知识,可以扯出一大堆,就像要考你计算机网络的知识时,问你"输入URL回车之后,究竟发生了什么"一样,看看你能说出多少了. 之前腾讯 ...

随机推荐

  1. SQL语言学习-DQL条件查询

    条件查询 1. where子句后跟条件 2. 运算符 * > .< .<= .>= .= .<> * BETWEEN...AND * IN( 集合) * LIKE: ...

  2. Vue 生产环境(production) 打开 调试工具的方法

    总所周知,在production生产环境下,点击vue插件会显示, 并且按F12是没办法使用调试工具的,这样非常不方便 其实是有一个办法的,那就是复制下面的js,然后在控制台执行 代码中已经写清楚执行 ...

  3. 【面试普通人VS高手系列】ConcurrentHashMap 底层具体实现知道吗?实现原理是什么?

    之前分享过一期HashMap的面试题,然后有个小伙伴私信我说,他遇到了一个ConcurrentHashMap的问题不知道怎么回答. 于是,就有了这一期的内容!! 我是Mic,一个工作了14年的Java ...

  4. Apache Doris 单节点(可多节点)Docker集群制作教程

    集群制作Author:苏奕嘉脚本研发Author:种益调研测试Author:杨春东 前言 Apache Doris是当下非常火热和流行的MPP架构OLAP数据库,很多同学想自学/测试Doris的使用和 ...

  5. python学习-Day29

    目录 今日内容详细 反射实际案例 面向对象的双下方法 __ str __ __ del __ __ getattr __ __ setattr __ __ call __ __ enter __ __ ...

  6. Spring 源码(6)BeanFactoryPostProcessor怎么执行的?

    上一篇文章 https://www.cnblogs.com/redwinter/p/16167214.html 解读了如何进行自定义属性值的编辑器的解析器,并且还介绍了BeanFactory的准备过程 ...

  7. [STL] stack 栈

    在出栈时需要进行两步操作,即先 top( ) 获得栈顶元素,再 pop( ) 删除栈顶元素

  8. Azure Service Fabric 踩坑日志

    近期项目上面用到了Azure Service Fabric这个服务,它是用来做微服务架构的,由于这套代码和架构都是以前同学留下来的,缺少文档,项目组在折腾时也曾遇到几个问题,这里整理如下,以供参考. ...

  9. Nacos源码系列—关于服务注册的那些事

    点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 项目源码地址:公众号回复 nacos,即可免费获取源码 简介 首先我们在看Nacos源码之前,要 ...

  10. data structure assignment problem record

    Question1: Similar to pause command in linux read -n 1 Question2 read : Illegal option -n 原因为ubuntu ...