客户端与连接的关系
如果是mysql自带的客户端,用mysql -u xxx这种方式连接服务端,那就是一个客户端对应一个连接;
如果是navicat、workbench这类有连接管理能力的工具,或者后端项目的连接池(如c3p0、druid、HikariCP等),那么一个客户端对应多个连接。
假设一个springboot项目配置如下
# 连接池配置
# 初始化大小,最小,最大
spring.datasource.initialSize = 10
spring.datasource.minIdle = 10
spring.datasource.maxActive = 10
项目启动后,执行第一个db操作,用show status like '%Threads_connected%';
可以看到mysql服务端的连接数增加了10
第1步
每收到一个连接请求,mysql服务端会从线程池中取一个线程负责此连接(每一个连接分配一个线程),由于线程太多会影响系统性能,所以服务端对连接数是有限制的;
mysql 5.7,最大连接数默认限制是151
show variables like 'max_connections'
max.png
第2步
对用户名、密码等信息认证,若认证失败,拒绝连接;
第3步
查询缓存,如果缓存中已有本次请求的查询结果,直接返回结果。由于mysql的缓存条件比较苛刻,而且维护缓存的开销较大,mysql从5.7开始不推荐使用缓存,8.0开始删除缓存功能。
缓存条件苛刻指的是,如果sql有符号的差别如空格、字母大小写等,可能导致缓存不命中,如果sql调用了now()等结果会变化的函数,这种请求不会被缓存.
维护缓存开销较大,是指缓存需要占用一定内存空间,以及需要监测与缓存有关的表,一旦变化,删除缓存(注意:是删除缓存,而不是保持一致性);
第4步
解析语法,形成mysql内部使用的数据结构(数据结构长什么样子?),然后优化,优化结果是执行计划,也就是explain看到的结果;
第5步
服务层调用存储引擎层的api,拿到数据,服务层过滤掉不满足条件的记录,把最后的结果返回给客户端。
mysql把数据的存储和提取操作交给存储引擎实现,不同的存储引擎提供了几十个统一的api,比如插入一行记录,从索引读一行记录,从索引读下一行记录等。返回数据的时候,会把数据先放到缓冲区,缓冲区满了才返回给客户端。
网友评论