文章目录
- [1. MySQL架构](#1. MySQL架构)
- [2. 连接层](#2. 连接层)
-
- [2.1 网络端口和连接管理线程](#2.1 网络端口和连接管理线程)
-
- [2.1.1 网络端口](#2.1.1 网络端口)
- [2.1.2 连接管理线程](#2.1.2 连接管理线程)
- [2.2 客户端连接线程管理](#2.2 客户端连接线程管理)
- [2.3 连接量管理](#2.3 连接量管理)
- [3. 服务层](#3. 服务层)
-
- [3.1 服务管理和公共组件](#3.1 服务管理和公共组件)
- [3.2 NoSQL接口与SQL接口](#3.2 NoSQL接口与SQL接口)
- [3.3 Parser(语法分析器)](#3.3 Parser(语法分析器))
- [3.4 Optimizer(查询优化器)](#3.4 Optimizer(查询优化器))
- [3.5 Caches & Buffers(缓存)](#3.5 Caches & Buffers(缓存))
- [3.6 SQL语句的执行流程](#3.6 SQL语句的执行流程)
1. MySQL架构
MySQL8.0服务器是由连接池、服务管理工具和公共组件、NoSQL接口、SQL接口、解析器、优化器、缓存、存储引擎、文件系统组成。MySQL还为各种编程语言提供了一套用于外部程序访问服务器的连接器。整体架构图如下所示:

MySQL Connectors:为使用MySQL服务的编程语言平台,提供了访问接口,可以根据自己实际使用的编程语言到官网下载地址下载。MySQL Shell:是一个高级客户端和代码编辑器,以组件的形式提供,需要单独安装。除了提供的类似于mysql客户端的功能,还可以使用JavaScript和Python调用MySQL的API,一般为开发人员使用。- 连接层:对客户端连接进行权限校验并保存客户端的连接信息,通过池化技术实现线程重用,以及根据具体的配置限制连接数量。
- 服务管理和公共组件:提供了数据备份与恢复,安全组件,主从复制和集群管理,表分区等实用功能。
- 服务层:提供了
NoSQL API,SQL API,SQL语句解析,SQL语句优化,SQL语句缓存等组件,并将优化后的SQL语句发送至存储引擎执行相应的操作并返回结果。- 存储引擎层:一系列可插拔的存储引擎,主要负责数据的写入和读取,与底层的数据和日志文件进行交互,可以根据具体的业务需求选择不同的存储引擎,后面我们具体介绍他们之间的区别。
- 文件系统层:包含了
MySQL发行版的文件和程序,以及具体数据库文件和日志。接下来我们介绍各层级在整个
MySQL服务器中实现的功能。
2. 连接层
连接层的作用是处理客户端的连接,这个小节主要介绍
MySQL Server如何管理连接,包括对可用连接接口的描述和服务器如何使用连接处理线程。
2.1 网络端口和连接管理线程
2.1.1 网络端口
一台服务器能够侦听多个网络端口上的客户端连接,开放多个端口,只需在选项文件中指定多个端口即可,配置如下所示:
mysql
[mysqld] # mysqld节点
port=3306 # 端口1
port=3307 # 端口2
2.1.2 连接管理线程
通过连接管理器线程处理端口上的客户端连接请求:
- 在所有平台上,用一个管理器线程处理所有的
TCP/IP连接请求。- 在
Unix上,管理器线程还可以处理其他Unix socket连接请求。- 在
Windows上,使用一个管理器线程处理通过Shared-memory方式连接请求,使用另一个管理器线程处理Named-pipe方式连接请求。- 在所有平台上,可以额外启用一个端口用于接受针对管理的
TCP/IP连接请求,管理端口的连接可以使用处理"普通"TCP/IP请求的管理器线程,也可以通过选项文件配置单独的线程(不做讨论)。
2.2 客户端连接线程管理
连接管理器线程在接收到每个客户端连接后,把请求转发到真正的执行线程,每个请求都对应一个执行线程,该线程处理连接的身份验证和具体请求。执行线程使用线程池技术进行缓存,当一个请求需要处理时,先从线程池中查找是否有可用的线程,如果没有则新创建一个,当连接结束时,如果线程池没有满,则把当前线程放入线程池,主要的作用是提高线程的复用,减少创建线程造成的系统开销从而提高效率。
可以通过以下几个系统变量和状态变量控制和监视服务器管理客户端连接的线程:
- 系统变量
thread_cache_size决定了线程池缓存的大小。默认情况下,服务器在启动时会自动调整这个值,但也可以通过选项文件明确指定大小,值为0时禁用缓存,此时为每个新连接创建执行一个线程,并在连接断开时释放;- 有些复杂的
SQL语句在执行过程中可能会有深层递归从而消耗更多的内存,通过设置thread_stack=N调整线程堆栈大小;- 要查看缓存中的线程数以及超过缓存数后新创建的线程数,通过状态变量
Threads_cached和Threads_created查看;
mysql
[mysqld] # mysqld节点
thread_cache_size=16 #线程池大小
thread_stack=1048576 #堆栈内存大小
thread_cache_size和thread_stack的大小需要根据机器的具体配置进行调整。
2.3 连接量管理
- 系统变量
max_connections可以控制服务器允许同时连接的最大客户端数,当服务器达到max_connections指定的连接数时会拒绝所有新的连接请求,同时会增加状态变量Connection_errors_max_connections的值;mysqld实际上允许max_connections+1个客户端连接。额外的连接为拥有CONNECTION_ADMIN权限的帐户(管理员)使用,即使普通连接达到了max_connections的数量,管理员也可以连接到服务器进行管理操作;- 在部署为主从复制的环境中,从节点的连接数也会计入
max_connections中,如果连接达到上限主从复制将会失败;max_connections具体数据和服务器的硬件有关,比如可用的内存、每个连接消耗的内存,每个连接的工作负载、响应时间、可用文件描述符的数量等等。
3. 服务层
数据库服务层是整个数据库服务器的核心,主要包括了服务管理和公共组件、
NoSQL和SQL接口、解析器、查询优化器和缓存等部分,下面我们分别介绍每个部分的作用。
3.1 服务管理和公共组件
MySQL提供了多种功能服务以满足不同使用场景下的需要,常用的服务如下:
Backup & Recovery:备份与恢复,在 备份与恢复专题介绍;Security:安全,在安全性与权限管理专题介绍;Replication:主从复制,在主从复制专题介绍;Cluster:MySQL集群,在MySQL集群专题介绍;Partitioning:表分区,在分库分表与表分区专题介绍;Instance Manager:实例管理,在系统数据库专题介绍;Administrator:MySQL管理员,在安全性与权限管理介绍专题;Migration Toolkit:迁移工具包,在安全性与权限管理专题介绍;
3.2 NoSQL接口与SQL接口
主要负责接收客户端发送的各种SQL语句和命令,并将SQL发送到其他部分,然后把接收到的结果返回给客户端。
3.3 Parser(语法分析器)
语法分析器的主要作用是将客户端发来的SQL语句中的关键字和自定义字段进行提取、解析,最终将 SQL 语句转换为一棵解析树,分析的过程中包含词法分析和语法分析.
- 词法分析,主要是对关键字进行提取,比如
select/update/delete/create... ;- 语法分析,主要判断
SQL语句是否满足语法规则,如果语法错误则异出异常,也就是我们常见的:ERROR 1064 (42000): You have an error in your SQL syntax。
mysql
# 例如有如下SQL语句, 对应的解析树大致如图所示
select sn, name from student where id = 1;

3.4 Optimizer(查询优化器)
通过语法校验的
SQL语句将进入查询优化器处理阶段,查询优化器会将解析树转化为查询计划,一般情况下,一条查询可以有很多种执行方案,查询优化器会根据执行计划匹配合适的索引,选择最佳的执行方案,最终把确定要执行的SQL交给执行器调用存储引擎API。
TIPS:优化后的SQL语句在条件查询时可能与程序员写的条件过滤顺序不同,但最终的返回结果一致,具体的优化过程我们在查询优化专题中介绍。
3.5 Caches & Buffers(缓存)
MySQL的缓存主要的作用是为了提升查询的效率,当服务器接收到一个 select 查询语句时,会先进入缓存查询当前SQL语句在缓存中是否存在,缓存以 key 和 value 的形式存储,key是具体的SQL语句,value是结果的集合,如果命中缓存,直接返回结果,无法命中缓存,则进入分析器进行正常查询流程。这里需要说明的是,缓存数据对应的数据在被更新之后将会失效,尤其在写多读少的场景中,缓存会频繁失效与新增,命中率非常低,因此MySQL5.6之后服务层缓存功能默认关闭,而且在MySQL8.0中服务层缓存被官方删除,这里不做过多讨论。
3.6 SQL语句的执行流程
如下图所示:
