MySQL原理(二):逻辑架构和执行流程

前言

上一篇介绍了 MySQL 默认的 InnoDB 存储引擎是如何存储和组织数据的,这一篇将介绍 MySQL 的逻辑架构,以及分析一条 SQL 语句的具体执行过程。

逻辑架构

在这里插入图片描述

MySQL 的架构共分为两层:Server 层和存储引擎层

  • Server 层负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在这实现,主要包括连接器,查询缓存、分析器、预处理器、优化器、执行器等。另外,所有的内置函数(如日期、时间、数学和加密函数等)和所有跨存储引擎的功能(如存储过程、触发器、视图等)都在 Server 层实现。
  • 存储引擎层负责数据的存储和提取。支持 InnoDB、MyISAM、Memory 等多个存储引擎,不同的存储引擎共用一个 Server 层。现在最常用的存储引擎是 InnoDB,从 MySQL 5.5 版本开始, InnoDB 成为了 MySQL 的默认存储引擎。我们常说的索引数据结构,就是由存储引擎层实现的。

执行流程

连接器

连接的过程需要先经过 TCP 三次握手,因为 MySQL 是基于 TCP 协议进行传输的。

TCP 网络连接建立成功后,服务端与客户端之间会建立一个 session 会话,紧接着会对登录的用户名和密码进行效验,首先会查询自身的用户表信息,判断输入的用户名是否存在,如果存在则会判断输入的密码是否正确。密码正确后,会从连接池中分配一条空闲线程维护当前客户端的连接;如果没有空闲线程,则会创建一条新的工作线程。之后线程会查询用户所拥有的权限,并对其授权,后续 SQL 执行时,都会先判断是否具备相应的权限。

空闲连接在超过最大空闲时长(wait_timeout)之后,连接器会自动将它断开。

一个处于空闲状态的连接被服务端主动断开后,客户端并不会马上知道,等到客户端在发起下一个请求的时候,才会收到报错。

连接池

Connection Pool,是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请、使用、释放。主要是为了复用线程、管理线程以及限制最大连接数。

当一个客户端尝试与 MySQL 建立连接时,MySQL 内部都会派发一条线程负责处理该客户端接下来的所有工作。

线程的频繁创建和销毁都会耗费大量资源,通过复用线程的方式,不仅能减少开销,还能避免内存溢出等问题。

数据库连接池可以设置最小连接数和最大连接数:

  • 最小连接数:是连接池一直保持的数据库连接,如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。
  • 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中。

查询缓存

连接器的工作完成后,客户端会向 MySQL 服务器发送 SQL 语句,MySQL 服务器收到 SQL 语句后,就会分析出 SQL 语句的第一个字段,看看是什么类型的语句。

如果查询语句(select 语句),MySQL 就会先去查询缓存( Query Cache )里查找缓存数据,看看之前有没有执行过这一条命令,这个查询缓存是以 key-value 形式保存在内存中的,key 为 SQL 查询语句的哈希值,value 为 SQL 语句查询的结果。

如果查询的语句命中查询缓存,那么就会直接返回 value 给客户端。如果查询的语句没有命中查询缓存中,那么就要往下继续执行,等执行完后,查询的结果就会被存入查询缓存中。

查询缓存往往弊大于利,因为只要有对表的更新,就会导致表上的所有查询缓存被清空。所以,MySQL8.0 版本直接将查询缓存删掉了。

这里说的查询缓存是 server 层的,也就是 MySQL8.0 版本移除的是 server 层的查询缓存,并不是 Innodb 存储引擎中的 buffer poll。

分析SQL

在正式执行 SQL 查询语句之前, MySQL 会先对 SQL 语句做分析,这个工作交由由分析器来完成。分析器可以将输入的 SQL 语句转换为计算机可以理解的形式(语法树,Syntax Tree)。

分析器会做如下两件事情:

  • 词法分析:MySQL 会根据输入的字符串识别出关键字出来,构建出 SQL 语法树。

  • 语法分析:根据词法分析的结果,语法分析器会根据语法规则,判断输入的 SQL 语句是否满足语法规则。

语法树大致结构如下:

在这里插入图片描述

当词法分析和语法分析出错时,分析器会抛出异常。比如语法结构出错、出现了无法识别的字符等。

表或者字段不存在,并不是在分析器里做的,而是在预处理阶段完成。

执行SQL

每条 SQL 语句主要可以分为以下这三个阶段:

  • prepare ,预处理阶段;
  • optimize ,优化阶段;
  • execute ,执行阶段;
预处理器
  • 检查 SQL 查询语句中的表或者字段是否存在;
  • select * 中的 * 符号,扩展为表上的所有字段
优化器

优化器会根据语法树制定多个执行计划,然后确定最优的执行计划。

  • 在表里存在多个索引的时候,决定使用哪个索引;
  • 在一个语句有多表关联(join)的时候,决定各个表的连接顺序;
执行器

判断用户权限,然后根据执行计划执行 SQL 语句。

Select流程

执行一条查询语句大致过程如下:

  1. 连接器:建立连接、校验用户身份和权限;
  2. 查询缓存:如果开启了查询缓存,则需要判断是否命中,如果命中查询缓存则直接返回,否则继续往下执行;
  3. 分析器:通过词法分析和语法分析构建语法树,并知道这是一条查询语句;
  4. 执行器:
    1. 预处理阶段:检查表或字段是否存在;将 select * 中的 * 符号扩展为表上的所有列;
    2. 优化器决定要使用的索引等,选择查询成本最小的执行计划;
    3. 执行器根据执行计划执行 SQL 查询语句,从存储引擎读取记录,返回给客户端。

Update流程

更新语句也类似于查询语句,在执行前需要:

  1. 连接器连接数据库。
  2. 分析器通过词法分析和语法分析知道这是一条更新语句。
  3. 优化器决定要使用的索引等。
  4. 执行器负责具体的执行过程。

执行器更新一条记录的具体流程如下:

  1. 执行器负责具体执行,会调用存储引擎的接口,通过主键索引树搜索获取 id=1 这一行记录:
    • 如果 id=1 这一行所在的数据页本来就在内存 Buffer Pool 中,就直接返回给执行器更新;
    • 如果记录不在内存 Buffer Pool,将数据页从磁盘读入到内存 Buffer Pool,返回记录给执行器。
  2. 执行器得到聚簇索引记录后,会看一下更新前的记录和更新后的记录是否一样:
    • 如果一样的话就不进行后续更新流程;
    • 如果不一样的话就把更新前的记录和更新后的记录都当作参数传给 InnoDB 层,让 InnoDB 真正的执行更新记录的操作;
  3. 开启事务, InnoDB 层更新记录前,首先要记录相应的 undo log,因为这是更新操作,需要把被更新的列的旧值记下来,也就是要生成一条 undo log,undo log 会写入 Buffer Pool 中的 Undo 页面,不过在内存修改该 Undo 页面后,需要记录对应的 redo log。
  4. InnoDB 层开始更新记录,会先更新内存(同时标记为脏页),然后将记录写到 redo log 里面(先写到内存中的 redo log buffer 中,再根据刷盘规则写入到 redo log 文件),这个时候更新就算完成了。为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘。(WAL 技术)
  5. 至此,一条记录更新完了。
  6. 在一条更新语句执行完成后,然后开始记录该语句对应的 binlog,此时记录的 binlog 会被保存到 binlog cache,并没有刷新到硬盘上的 binlog 文件,在事务提交时才会统一将该事务运行过程中的所有 binlog 刷新到硬盘。
  7. 事务提交(为了方便说明,这里不说组提交的过程,只说两阶段提交):
    • prepare 阶段:将 redo log 对应的事务状态设置为 prepare,然后将 redo log 刷新到硬盘;
    • commit 阶段:将 binlog 刷新到磁盘,接着调用引擎的提交事务接口,将 redo log 状态设置为 commit(将事务设置为 commit 状态后,刷入到磁盘 redo log 文件);

最后

本文介绍了 MySQL 的逻辑架构和执行流程。逻辑架构分为 Server 层和存储引擎层。执行流程主要是在 Server 层完成的,主要由连接器、分析器、优化器、执行器完成。

下一节将介绍 MySQL 的索引。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值