MySQL 可以分为 Server 层和存储引擎层两部分
server层包括 连接器.查询缓存.分析器.优化器.执行器等,涵盖MYSQL的大多数核心服务功能,以及所有的内置函数(如 日期.时间.数学和加密函数等),所有的跨存储引擎的功能都能在server层进行实现,比如 存储过程 触发器 视图等.
而存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎.
执行流程
- 先进入连接器,根据用户名和密码确认是否能够建立链接
- 连接成功后进行查询缓存阶段,缓存以key-value的形式存在,key为查询语句,value为查询返回的结果,查询缓存成功将直接返回给客户端 (*不推荐使用查询缓存) ,如果命中缓存会进行权限校验
- 如果么有命中缓存将进行执行sql语句操作,进入分析器阶段,分析器进行校验sql语句的操作,sql语句操作将直接返回错误
- 校验完成sql语句之后,将进入优化器阶段,优化器会选择一中合理的执行方案
- 选择完合理的执行方案将进入执行器操作阶段,执行器会进行权限校验,检验完成,执行器会将查询到的结果集返回给客户端
server层
连接器
- 连接器负责跟客户端建立连接.获取权限,维持和管理连接,验证用户名字和密码,验证通过后会到权限表中查询出你拥有的权限.之后这个连接里面的权限判断逻辑,都将依赖于此时读取到的权限,也就意味着一个用户只要建立了连接,即使这个时候该用户的权限受到更改也不会影响到这个连接已存在的权限,修改完权限后只有重新建立连接才会使用新的权限设置.
- 客户端长时间不操作,连接器会自动断开连接,这个时间限制是由
wait_timeout控制的默认是8小时 - 连接断开后,客户端再次发起请求将受到
Lost connection to MYSQL server during query.错误提示,需要重新连接才能再次执行请求 - 数据库中,长连接是指连接成功后,客户端有持续的请求将继续使用当前连接,短连接是指每次执行完很少的几次查询就断开连接,下次查询将简历一个新的连接
- 建立连接是复杂的操作,我们应该尽量的去减少连接动作,也就是尽量去使用长连接
- 如果全部使用场链接,就会出现MYSQL的内存涨的非常快,因为MYSQL在执行过程中临时使用的内存是管理连接对象里面的,这些资源会在连接断开的时候释放掉,所以长连接累积下来,可能会导致内存占用过大,被系统杀掉,从现象体现就是MySQL异常重启
- 如何解决?
- 定期断长连接,使用一款时间后,或者判断执行一个占用内存大的查询中之后,断开连接之后要查询再进行重连
- 如果是MYSQL5.7以上的版本,再执行一个比较大的操作之后,通过执行
mysql_rest_connection可以重新初始化连接资源,这个过程不需要做权限验证和重连,会将连接恢复到刚刚创建完成的状态
查询缓存(MySQL8.0查询缓存被整块删除)
- MYSQL拿到一个查询请求后,会先查询缓存,看看之前是否执行过这条语句.之前执行过的语句和结果可能会以key-value的形式,被缓存在内存中,key是查询语句value是查询结果,如果能找到缓存,再鉴定完权限之后会直接返回给客户端.大多数情况下建议不使用缓存,因为查询缓存往往弊大于利因为查询缓存失效是非常频繁的,只要有一个表的更新,这个表上的所有查询缓存都将被清空,对于更新压力大的数据库来说,查询缓存的命中率非常低,除非是一张静态表比如系统配置表,很长时间才会进行一次更新
- MySQL也提供了按需使用查询缓存的方式,可以将参数
query_cache_type设置成DEMAMD,这样默认的sql语句都不将使用查询缓存,而对于要使用查询缓存的语句可以通过SQL_CACHE显式指定如:select SQL_CACHE * from user where id=1; - MySQL8/0版本直接将查询缓存的整块功能删掉了分析器
如果没有名中国缓存,就要开始真正的执行sql语句,首先MySQL需要孩子欧东你要做什么,因此需要对sql语句进行解析- 分析器会先做’词法分析’.sql语句是由多个字符以及空格组成的.mysql需要识别出里面的字符串分别是什么代表什么
- 识别完词法后,要开始进行’语法分析’,语法分析会根据语法规则,判断sql语句是否满足MySQL语法,如果语句不对将会受到
You haave an error in your SQL syntax,一般语法错误提示会提示第一个出现错误的位置,所以要关注紧接着的use near的内容优化器
进过完分析器之后,MySQL就会知道你要做什么,再开始执行之前会,还要经过优化器的处理
- 优化器实在表中有多个索引的时候决定使用哪种索引,或者一个语句有多个关联表的时候决定各个表的连接顺序,优化器会根据执行效率的不同决定使用哪一种执行方案执行器
MySQL通过分析器知道你要做什么,通过优化器知道了你要怎么做,于是执行器就开始进行执行语句- 开始执行的时候要先从连接器的拿到的权限进行校验是否拥有该表的查询权限,如果没有就返回没有权限的错误提示
- 如果有权限,就打开表继续执行,执行器会根据表的引擎定不会以,去使用引擎提供的接口 执行器的执行流程如下
- 调用InnoDb引擎接口读取到这个表的第一行,判断是否符合条件,如果不是则跳过,如果是就将这行的数据存在结果集当中
- 调用引擎接口取”下一行”进行相同的判断直至最后一行
- 执行器将是所有满足条件的数据行组成的结果集返回给客户端 至此整个语句就执行完成了

