MySQL架构
# MySQL架构
前言
目前大部分的后端开发人员对 MySQL
的了解和使用只停留在建库、建表、建索引,执行各种增删改查操作,完全不了解内部的架构和原理。下面我们就来简单了解以下MySQL的架构。
文章参考:重学MySQL系列01-揭开面纱,显露架构 (opens new window)
# 整体架构
MySql 架构分为 Server 层与存储引擎层
- Server 层:负责连接管理、解析与优化这些不涉及读写数据的操作,后面将详细介绍 Server 层
- 存储引擎层:负责读写数据,我们了解的存储的引擎有 InnoDB 和 MyISAM
整体架构如下图所示,下面我们就详细看看 MYSQL 的 Server 层到底做了什么:
# 连接管理
系统(客户端)访问 MySQL 服务器前,做的第一件事就是建立 TCP 连接。
经过三次握手建立连接成功后,MySQL 服务器对 TCP 传输过来的账号密码做身份认证、权限获取。
- 用户名或密码不对,会收到一个
Access denied for user
错误,客户端程序结束执行 - 用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依赖于此时读到的权限
同一时刻,可以有多个系统和 MySQL 服务器建立连接,每个系统建立的连接肯定不止一个。所以,为了解决 TCP 无限创建与 TCP 频繁创建销毁带来的资源耗尽、性能下降问题。MySQL 服务器里有专门的 TCP 连接池限制接数,采用长连接模式复用 TCP 连接,来解决上述问题。
TCP 连接收到请求后,必须要分配给一个线程去执行,所以还会有个线程来负责后面的流程。这些内容我们都归纳到 MySQL 的连接管理组件中。
所以连接管理的职责是负责认证、管理连接、获取权限信息。
# 解析与优化
# 查询缓存
经过了连接管理,现在 MySQL 服务器已经获取到 SQL 字符串。
如果是查询语句, MySQL 服务器会使用 select SQL
字符串作为 key 。去缓存中查询:
- 如果命中缓存则直接返回结果(返回前需要做权限验证)
- 未命中执行后面的阶段
需要注意,select SQL
字符串要完全匹配,有任何不同的地方都会导致缓存不被命中(空格、注释、大小写、某些系统函数)
小贴士:虽然查询缓存有时可以提升系统性能,但也不得不因维护这块缓存而造成一些开销,从MySQL 5.7.20开始,不推荐使用查询缓存,并在MySQL 8.0中删除。
# 分析器
没有命中缓存,或者非 select SQL
就来到分析器阶段了。因为系统发送过来的只是一段文本字符串,所以 MySQL 服务器要按照 SQL 语法对这段文本进行解析。
如果你的 SQL 字符串不符合语法规范,就会收到 You have an error in your SQL syntax
错误提醒
# 优化器
通过了分析器,说明SQL
字符串符合语法规范,现在 MySQL 服务器要执行 SQL 语句了。首先需要产出执行计划,交给 MySQL 服务器执行,所以来到了优化器阶段。
优化器不仅仅只是生成执行计划这么简单,这个过程它会帮你优化 SQL 语句。如外连接转换为内连接、表达式简化、子查询转为连接、连接顺序、索引选择等一堆东西,优化的结果就是执行计划。
# 执行器
截止到现在,还没有真正去读写真实的表,仅仅只是产出了一个执行计划。于是就进入了执行器阶段, MySQL 服务器终于要执行 SQL 语句了。
开始执行的时候,要先判断一下对这个表有没有相应的权限,如果没有,就会返回权限错误。如果有权限,根据执行计划调用存储引擎 API 对表进行的读写。
存储引擎 API 只是抽象接口,下面还有个存储引擎层,具体实现还是要看表选择的存储引擎。
# 总结
MySql 架构分为 Server 层与存储引擎层
- Server 层:负责连接管理、解析与优化
- 连接管理:负责认证、管理连接、获取权限信息
- 解析与优化:查询缓存、SQL语法解析验证、SQL优化并生成执行计划、根据执行计划调用存储引擎接口
- 存储引擎层:负责读写数据
通过这种架构设计,我们发现 Server 层其实就是公用层,存储引擎层就是多态层,按需选择具体的存储引擎。