先放一张图:
从MySQL的架构图来看,mysql一共有两种连接方式
各语言封装的客户端连接器
MySQL Shell 脚本直连
进入MySQL Server端后包含了三大分类
连接管理器层(服务端)
用来客户端连接器请求过来以后,验证账户和密码,不正确,立马返回Access denied for user
,
验证通过,查询账户拥有的权限,并缓存起来;
此链接是一个长链接(长链接的好处就不说了),MySQL也不会让你啥也不干一直连着,所以就有了超时时间,由wait_timeout
控制(断开是服务器端断开,客户端再请求过来就报 Lost connection to MySQL server during query)
链接器采用池化技术,节省了创建和销毁的成本;
一个客户端请求服务端分配一个线程(从线程里取),把线程池占满了,再连就报连接满了;
客户端一般也采用池化技术,优化请求,防止每次执行SQL都需要建立连接,减少开销;
长连接带来一个问题,有些SQL在执行的过程中将对象绑定到连接上,连接不释放,内存不回收,会导致MySQL占用内存涨的特别快,可以通过以下方式解决
定期断开长连接(需要重连和权限验证)
MySQL5.7或更新的版本,可以通过执行mysql_reset_connection来重新初始化连接(相比上一个方案,不需要重连和权限验证)
解析与优化层
在解析与优化这一层,有两个接口,一个是MySQL操作SQL的接口,一个是MySQL操作NoSQL的接口,这块主要是让制定标准,让大家使用的时候,按标准来
NoSQL 操作的接口 从5.7.12就可以使用,在8.0中默认就启用了(需要启用x plugin)
查询缓存(MySQL8 将这块删除了)
MySQL接收到请求后,会先看缓存中有没有(之前查询的结果会以k-v的方式存储在内存里,k是语句,v是结果)
一般情况下查询缓存的命中率是非常低的(除非你的数据是静态的)
可以通过在select 后加SQL_CACHE
来显示指定使用查询缓存
缓存
mysql8中是全局缓存,以及引擎缓存,比如InnoDB的cache buffer
比如表记录,权限这些都是全局缓存
解析器
MySQL在真正执行语句之前,会去parser你的查询语言,了解你要做什么
在这个过程会判断你的语法是否正确
将查询字段,表,条件封装到内部的数据结构上形成解析树
优化器
通过语法解析,MySQL知道你的真实意图了,但你写的SQL不一定是高效的
这个时候MySQL会给我们的SQL做些优化调整,比如:使用哪个索引,外连接转换为内连接,多表连接的时候,表的连接顺序
从而确定最终的执行方案
这个优化策略主要有两种:静态优化(编译时优化) 和动态优化(运行时,sql基本上都是动态)
等价变换策略:比如 x<y and x=5 优化为y>5 and x=5,以及联合索引的位置调整
函数查询优化:比如:min 直接从索引的左侧开始查,max从右;
in的优化:先对in的条件进行优化,再进行二分查找
执行器
解析完了,也优化完了,那就该执行了
别急,还没完,你有权限吗?没有,直接拒绝执行,有才可以执行
执行器操作的是下一层的存储引擎
存储引擎层(可插拔)
MySQL将操作封装成了接口,屏蔽了不同存储引擎的差异,各种存储引擎实现了这些操作接口,内部又差异化的做了各种扩展;
比如InnoDB锁的粒度到表级,InnoDB的事务,都是差异性的
我们可以通过show engines
来查看支持的存储引擎
存储引擎同一个实例只能启用一种
文件系统层
文件系统由各操作系统提供
MySQL将其持久化的数据物理存储在磁盘上,持久化保存数据、索引、binlog、redolog、undolog、error日志、慢sql等;
因篇幅问题不能全部显示,请点此查看更多更全内容