看一个事儿千万不要直接陷入细节里,你应该先鸟瞰其全貌,这样能够帮助你从高维度理解问题。——丁奇

MySQL 基本架构

在我理解MySQL的基本架构可以大概分为三个部分:客户端、Server 层、存储引擎。

客户端负责与 Server 层建立连接,Server 层负责 SQL 语句的执行处理,存储引擎负责存储数据。架构还是比较明确的。

Server层的每个部分功能单一明确:

  • 连接器——管理连接,权限验证
  • 分析器——词法分析,语法分析
  • 查询缓存——命中缓存,直接返回
  • 优化器——生成执行计划,选择索引
  • 执行器——操作引擎,返回结果

而存储引擎则顾名思义:负责存储数据并提供操作接口。

如图所示:

MySQL基本架构

架构清晰,其中存储引擎架构模式是插件式的,支持不同种类。MySql 5.5 版本之后,InnoDB 成为了默认的存储引擎。

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

客户端与服务端通过 TCP 协议进行通信,三次握手加认证后建立连接,通过后连接器从权限表直接查出来所拥有的权限。

所以可以看出来,用户的权限在当次连接建立之后是不可变更的。

连接管理

执行 select 语句后的第一步就是建立连接。

查看连接指令:

show processlist

查询后的结果如图所示:

processlist

其中 Command 一列表示连接状态:sleep 表示该连接空闲。

连接分为长连接和短连接两种。

利用长连接避免了复杂的建立连接的过程,但是带来的一个问题是如果连接过多,则可能占用内存太大,造成 OOM 错误。

针对此,丁奇给出了两种备选的解决方案:

1.定期断开长连接。

2.每次执行一个比较大的操作后,通过 mysql_reset_connection 命令重新初始化资源。注意这个过程不需要重新建立连接和权限验证,只是会恢复到刚刚建立完全的状态。

缓存查询

第二步就是查询缓存。

收到 query 请求后,首先看看缓存,是否执行过该语句。

指令在缓存中存储的形式是 key-value 对,其中 key 是查询语句,value 是查询结果。

这样看起来缓存貌似会提高一点查询效率,但是事实上,缓存会带来很多问题:

查询缓存的失效比较频繁(只要有对一个表的更新,这个表上的所有查询缓存都会被清空),所以这对静态表来说比较适合。

分析器

这一步需要做的是对 SQL 语句的一个解析。

主要分为两种:

1.词法分析

分别找出每个字符串代表什么,也就是弄懂每个单词的意思。

2.语法分析

弄懂每个单词的意思后,接下来要根据语法规则判断输入的 SQL 语句是否满足语法。

经过这两个分析,MySql 就知道了 SQL 语句的意思了,解决的是“要做什么”的问题。

优化器

这一步是处理一些特殊的事情。

比如数据表里使用了索引,而且有时候还不止一个,这个时候它就来做决定,到底是使用哪个索引;数据表做了关联(join),决定表的连接顺序。

所以优化器的作用是决定采取哪些方案,解决的是”怎么做“的问题。

执行器

这一步开始真正执行。

首先判断用户对表的权限问题,进行权限验证。

调用存储引擎的接口进行查询,将查询到的结果记入结果集中,继续进行下一个遍历。

执行完毕之后,将结果集返回给客户端。

参考文献

1.丁奇《MySQL实战45讲》