MySQL连接执行全过程涉及哪些细节和步骤?
摘要:执行流程图 MySQL 的架构可以大致划分为四个层次:连接层、服务层、存储引擎层和文件系统层。 连接层:负责对来自客户端的连接进行权限验证,并将连接信息存入连接池中,方便后续的连接复用。 服务层:主要负责 SQL 语句的解析与优化,还包括查
执行流程图
MySQL 的架构可以大致划分为四个层次:连接层、服务层、存储引擎层和文件系统层。
连接层:负责对来自客户端的连接进行权限验证,并将连接信息存入连接池中,方便后续的连接复用。
服务层:主要负责 SQL 语句的解析与优化,还包括查询缓存和 MySQL 内置函数的实现。
存储引擎层:提供多种可插拔的存储引擎,允许我们通过不同的引擎进行数据的存取操作。存储引擎使得 MySQL 能够直接与硬盘上的数据和日志进行交互,用户可以根据需求选择合适的引擎。从 MySQL 5.5 版本开始, InnoDB 成为了 MySQL 的默认存储引擎。
文件系统层:这一层主要包括日志文件、数据文件及与 MySQL 相关的其他程序。在这四个层次中,服务层和存储引擎层构成了架构的核心。服务层负责处理 MySQL 的核心逻辑,而存储引擎层则直接负责数据的存取操作。
也可以将其简单的分成两层:Server 层和存储引擎层,如图
Server 层:负责建立连接、分析和执行SQL。主要包括连接器、查询缓存、分析器、优化器、执行器等。这些组件包含了MySQL的大部分主要功能。
存储引擎层:负责数据的存储和提取。
连接器
客户端需要通过连接器访问MySQL Server,连接器主要负责身份认证和权限鉴别的工作。也就是负责用户登录数据库的相关认证操作,例如:校验账户密码,权限等。在用户名密码合法的前提下,会在权限表中查询用户对应的权限,并且将该权限分配给用户。
如何查看有多少连接?
执行 show processlist 命令进行查看
其中”Command”列返回的内容中,“Sleep”表示MySQL相同中对应一个空闲连接。而“Query”表示正在查询的连接。
连接状态:
Command
含义
sleep
线程正在等待客户端发数据
query
连接线程正在执行查询
locked
线程正在等待表锁的释放
sorting result
线程正在对结果进行排序
sending data
向请求端返回数据
空闲连接是否一直存在
从上图可以看出有许多空闲连接,MySQL 定义了空闲连接的最大空闲时长,由 wait_timeout 参数控制的,默认值是 8 小时(28880秒),如果空闲连接超过了这个时间,连接器就会自动将它断开。
手动断开空闲的连接,使用的是 kill connection + id 的命令
最大连接数
长连接和短连接
长连接是指连接成功后,客户端请求一直使用是同一个连接。
短连接是指每次执行完SQL请求的操作之后会断开连接,如果再有SQL请求会重新建立连接。
由于短连接会反复创建连接消耗相同资源,因此多数情况下会选择长连接。但是为了保持长连接,会占用系统内存,而这些被占用的内存知道连接断开以后才会释放。这里提出了两个解决方案:
定期断开长连接,每隔一段时间或者执行一个占用内存的大查询以后断开连接,从而释放内存,当查询的时候再重新创建连接。
客户端主动重置连接。MySQL 5.7 或者更高的版本,通过执行 mysql_reset_connection 来重新初始化连接。此过程不会重新建立连接,但是会释放占用的内存,将连接恢复到刚刚创立连接的状态。
查询缓存
在建立与数据库的连接以后就可以执行SQL语句了
如果 SQL 是查询语句(select 语句),MySQL 就会先去查询缓存( Query Cache )里查找缓存数据,看看之前有没有执行过这一条命令,并且将执行结果按照key-value的形式缓存在内存中了。
Key 是查询的SQL语句,Value 是查询的结果。如果缓存 Key 被命中,就会直接返回给客户端,如果没有命中,就会执行后续的操作,执行完SQL仍旧会把结果缓存起来,方便下一次调用。
Mysql的机制是只要一个表有更新操作,那么这个表的查询缓存就会被清空。如果张表不断地被使用(更新、查询),那么查询缓存会频繁地失效,获取查询缓存也失去了意义。不过可以运用在一些修改不频繁的数据表。例如:系统配置、或者修改不频繁的表。
缓存的淘汰策略是先进先出,适用于查询远大于修改的情况下, 否则建议使用Redis或者其他做缓存工具。因此大多数情况下不推荐使用查询缓存。MySQL 8.0 版本后删除了查询缓存的功能,官方认为该功能应用场景较少,所以将其删除。
这里说的查询缓存是 server 层的,与Innodb 存储引擎中的 buffer pool的缓存无关。也就是 MySQL 8.0 版本移除的是 server 层的查询缓存,
解析 SQL
在正式执行 SQL 查询语句之前, MySQL 会先对 SQL 语句做解析,这个工作交由「解析器」来完成。
