本篇主要介绍一下MySQL的架构
目录
一、整体架构
二、连接层
网络端口
连接管理线程
三、服务层
NoSQL接口与SQL接口
Parser(语法分析器)
Optimizer(查询优化器)
Cache & Buffers(缓存)
四、存储引擎层
一、整体架构
MySQL的整体架构如下图所示:
下面我们来简单了解一下该图中各部分的含义:
- MySQL Connectors :指的是MySQL为各编程语言提供的访问接口,例如,JDBC,通过这些接口就能直接在编写的程序里访问MySQL。
- MySQL Shell : 是一个较为高级的MySQL客户端和代码编辑器,需要单独安装才能使用,除了具有MySQL客户端的功能之外还具有能够被JS语言,python语言调用访问的接口。通常情况下,MySQL Shell提供给数据库开发人员使用。
- 连接层:对来自客户端的连接进行权限验证并将相关的连接信息维护到连接池中,以便于下次连接。
- 服务管理和公共组件:提供了数据备份与恢复,安全组件,主从复制和集群管理、表分区等相关功能。
- 服务层:提供NoSQL,SQL的API,SQL解析,SQL语句优化,SQL语句缓存等相关组件。
- 存储引擎层:提供了一系列可插拔的存储引擎,我们可以通过存储引擎来进行数据的写入与读取,通过存储引擎,我们可以真正的与硬盘中的数据和日志进行交互我们可以根据需求来选择合适的存储引擎进行使用。
- 文件系统层:该层包含了具体的日志文件和数据文件以及MySQL相关的程序。
下面我们具体来了解一下该架构中的连接层,服务层和存储引擎层。
二、连接层
MySQL的连接层主要处理客户端与服务器的连接。
网络端口
在MySQL服务器中,可以开放多个端口来监听来自客户端的连接,但默认只使用3306进行监听,如果需要开启多个端口来监听,可以通过配置文件来设置,具体如下:
[mysqld] #服务器节点
port=3306 #监听端口1
port=3307 #监听端口2
连接管理线程
对于端口监听到的连接请求通过连接管理线程来处理,但针对不同的平台,连接管理线程的使用略有不同,具体如下:
- 在所有平台上,mysql都会创建一个连接管理线程来处理所有TCP/IP请求。
- 在unix平台上,这个连接管理线程则还能够用来 处理unix socket的连接请求。
- 在windows上,则会创建一个连接管理线程来处理Shared - memeory的连接请求,创建另一个连接管理线程来处理Named-pipe方式的连接请求
- 在所有平台上,都能额外开启一个端口单独用作TCP/IP请求的监听,然后使用前面说的处理所有TCP/IP请求的连接管理线程来处理这个端口上的请求,也可以通过配置文件,单独创建一个连接管理线程来处理这些连接请求。
下面我们来了解一下连接管理线程的工作流程:
连接管理线程在处理连接请求时会将请求一对一的转发给执行线程,由该执行线程来处理具体的的身份验证和处理连接请求。执行线程通过线程池进行管理,线程池会事先创建好执行线程并缓存,当有请求转发过来时,会先去该线程池中寻找是否有能够使用的执行线程,如果没有则创建一个 ,当该新建的执行线程处理完成请求后,会去看线程池是否还有空间,如果有则把该线程放入线程池,如果没有则销毁,使用线程池主要是提高线程的复用并减少创建线程所带来的开销以提高性能。
对于上面提到的线程池,我们可以通过一些系统变量来查看或设置与其相关的参数,具体如下:
thread_cache_size :线程池中缓存的大小,决定了能包含多少执行线程
thread_stack: 执行线程的堆栈大小,用来防止执行线程因递归太深等原因分配过多的内存用作栈空间
threads_cached:缓存中的线程数
threads_created : 超出线程池缓存,新创建的执行线程的数量
在MySQL中存在最大的允许同一时间连接的客户端数,该数通过系统变量max_connections来设置,如果连接数超过该值,则会拒绝所有的连接,并增加状态变量Connection_errors_max_connection的值,但也有例外,如果当前的连接请求是由具有管理员权限的用户发起的,则不会拒绝该连接请求,因此mysqld实际上是允许max_connections+1个客户端同时建立连接的。需要注意的是,在主从复制的环境中,从节点的连接也会被计入max_connections.max_connections的设定应该参照当前硬件环境的性能。
三、服务层
数据库服务层是mysqld的核心部分,下面我们来具体了解一下他各部分内容:
NoSQL接口与SQL接口
该部分主要用来接收和来自客户端的SQL语句,然后将语句转发给服务层的其它部分进行处理,最后再将 处理结果返回给客户端。
Parser(语法分析器)
语法分析的功能主要是将SQL中的关键字和用户定义的字段提取出来并分析,最终形成一棵解析树,分析的过程包括词法分析和语法分析,词法分析,主要是对关键字进行提取,比如“delete,create,select.....”。语法分析主要是分析SQL中是否有语法错误,也就是我们常见的ERROR1064 (42000):You have an error in your SQL syntax。
例如下面这条SQL
select sn, name from student where id = 1;
可以转换成如下解析树:
Optimizer(查询优化器)
通过词法分析器处理过后的语句将会交由查询优化器进行优化,查询优化器会根据前面生成的解析树生成一系列执行计划,然后根据查执行计划匹配索引,最终找到一条性能最好的执行计划,然后将该执行计划的SQL交给执行器,执行器就会调用存储引擎提供的api来真正执行该SQL。
Cache & Buffers(缓存)
MySQL的缓存主要用来提高查询语句的性能,当客户端传来一条查询的SQL时,会先去缓存中查是否存在该SQL,缓存中,SQL与SQL的执行结果通过key-value的方式进行组织,存在直接返回对应的value。如果不存在,则继续通过前面的词法分析器,查询优化器,以正常的流程执行该SQL。需要注意的是,如果缓存中的value中记录的数据发生了更改,也就是说当前该语句的执行结果已经变化了,则会删除这条缓存,因此在写多读少的情况下,命中缓存(使用缓存)的几率就会很低,而缓存的创建和修改操作则会十分频繁,从而浪费大量的性能,因此在MySQL8.0之后的版本,服务层的缓存已经被官方删除了,不再使用。
最后我们通过下图来具体看一下一条SQL在MySQL服务层的执行过程:
四、存储引擎层
存储引擎层用来具体完成SQL语句的执行以及与文件系统的交互,里面包含了一系列可插拔的存储引擎组件,用来处理并执行对应表类型的SQL,这些存储引擎组件,可以在MySQL运行时进行动态的加载和卸载。通过下面这条SQL,我们能够查看到当前MySQL支持哪些存储引擎:
show engines;
其中,NO表示支持,Yes表示不支持,default表示当前服务器在创建表时默认使用该存储引擎。有关这些存储引擎的特点和详细内容将在下一篇博客中介绍。