写点什么

MySQL 笔记(一)基础架构

用户头像
奈何花开
关注
发布于: 2020 年 06 月 07 日
MySQL 笔记(一)基础架构

一、整体概况

我们先通过一条简单的 SQL 聊一聊 MySQL 的基础架构。比如我们有个学生表,有 id,name,age 三个字段,执行如下语句时,它的内部执行过程是怎么样的呢?

SELECT * FROM student WHERE name = '张三';

从执行结果上看,我们执行了一条 SQL,给我们返回了 name='张三' 对应的这条记录。从 MySQL 的内部来看,它经过了 连接器、查询缓存、分析器、优化器、执行器等,最后到达存储引擎取出我们需要的数据。这些组件之间是如何协同工作的呢?让我们看下 MySQL 的逻辑架构图

MySQL 逻辑架构图

由图上可以看出,MySQL 大体上可以分为 Server 层和存储引擎层两部分。

  • Server 层:包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。

  • 存储引擎层:负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。

二、连接器

要使用 MySQL 数据库,第一步就是要连接上数据库,连接器就是负责这个连接操作的组件。连接器负责跟客户端建立连接、获取权限、维持和管理连接。连接一般分这么几种情况:

  • 命令行连接:mysql -h$ip -P$port -u$user -p

  • 工具连接:Navicat、SQLyog 等

  • 代码连接:各种数据库连接池,如 druid 等



执行连接操作时,连接器会在完成经典的 TCP 握手后,开始认证你的身份,这个时候用的就是你输入的用户名和密码。

  • 如果用户名或密码不对,你就会收到一个"Access denied for user"的错误,然后客户端程序结束执行。

  • 如果用户名密码认证通过,连接器会到权限表里面查出你拥有的权限。之后,这个连接里面的权限判断逻辑,都将依赖于此时读到的权限。



要注意的是,一个用户成功建立连接后,即使你用管理员账号对这个用户的权限做了修改,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。

三、查询缓存

回到我们开头的那条 SQL,连接建立后,执行 SELECT 查询语句,会先到查询缓存里查询,如果命中,直接返回;否则,继续后面的执行阶段。通常情况下,我们不建议使用查询缓存,查询缓存往往弊大于利。



因为在业务开发中,对一个表的更新是非常频繁的,这会导致查询缓存的失效也非常频繁。除非有一张很长时间才会更新一次的静态表。比如,系统配置表,那这张表上的查询才适合使用查询缓存。但是即使是这种静态表,也不太建议使用数据库的查询缓存,一般会使用 Redis 或 Mybatis 缓存。值得注意的是,MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了。

四、分析器

或者叫解析器,主要进行 SQL 解析、预处理操作。实际上,从分析器开始,才是真正开始执行 SQL 语句,因为这时才需要对 SQL 语句进行解析。分析器分为两步“词法分析”和“语法分析”两步,我们以开头的那条 SQL 为例

  • 词法分析:你输入的是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串分别是什么,代表什么。如:MySQL 从你输入的 SELECT 这个关键字识别出来,这是一个查询语句。它也要把字符串 student 识别成“表名 student”,把字符串“name”识别成“列 name”。接着会进行“语法分析”。

  • 语法分析:根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。如果不满足语法,会返回“You have an error in your SQL syntax”错误提示。

五、优化器

分析器之后,MySQL 就知道你要做什么了。但是在开始之前会再经过一个优化器的处理,比如表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序等。这一步会生成执行计划。

六、执行器

MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。

执行之前,会先判断该用户有没有执行查询的权限(如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用 precheck 验证权限)。

  • 没有权限:返回没有权限的错误,如:ERROR 1142 (42000): SELECT command denied to user 'xxx'@'localhost' for table 'student'

  • 有权限:继续往下执行,根据表的引擎定义,去调用这个存储引擎提供的接口。默认的存储引擎为 InnoDB 引擎。

七、小结

一条查询 SQL 的执行路径通常有这么几步:

  1. 客户端发送一条查询 SQL 给服务器

  2. 服务器先检查查询缓存(如果开启),如果命中了缓存,返回缓存的结果(返回之前会做权限验证);否则,进入下一阶段

  3. 服务器使用解析器对 SQL 进行解析、预处理。这一步会验证语法正确性并生成合法的解析树,也会做一些权限的验证

  4. 优化器根据解析器提供的解析树生成对应的执行计划

  5. MySQL 根据优化器生成的执行计划,调用存储引擎的 API 来执行查询

  6. 将结果返回给客户端

这里,我参照《高性能 MySQL》画了下查询语句的执行路径图:



用户头像

奈何花开

关注

还未添加个人签名 2019.05.14 加入

还未添加个人简介

评论

发布
暂无评论
MySQL 笔记(一)基础架构