架构
// TODO 架构图
大体来说,MySQL分为 Server层 和 存储引擎层 两部分
Server层包括:连接器、查询缓存、分析器、优化器、执行器。涵盖MySQL大多数核心服务功能,以及所有的内置函数(时间、日期、数学、加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎层:负责数据的存储和读取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等引擎。
Server层
连接器
负责跟客户端建立连接、获取权限、维持和管理连接
查询缓存
MySQL拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果会以 key-value 对的形式,直接缓存在内存中。key是查询语句,value是查询结果。
如果查询能在缓存中找到key,则直接返回value给客户端。如果找不到,就会继续后面的执行阶段,执行完成后,执行结果会被存入查询缓存中。
大多数情况下不要用查询缓存,因为往往弊大于利。
查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。MySQL8.0版本,直接将查询缓存功能整块去掉了。
分析器
如果没有命中查询缓存,就要开始真正执行语句了。首先MySQL需要知道要做什么,所以需要对SQL语句进行解析。
先做词法分析,识别语句中的字符串分别是什么、代表什么,识别出关键词,表名、列等。
再做语法分析,对词法分析的结果,根据语法规则,判断SQL语句是否满足MySQL语法。
优化器
表里有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联的时候,决定各个表的连接顺序。
执行器
MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。
开始执行的时候,要先判断一下你对这个表T有没有执行查询的权限。
如果没有,就会返回没有权限的错误(如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用precheck验证权限)
权限验证不仅会在执行器这部分会做,在分析器之后,也就是知道了该语句要干什么之后,也会先做一次权限验证,叫做precheck,而precheck是无法对运行时涉及到的表进行权限验证的,比如使用了触发器的情况。因此在执行器这里也要做一次执行时的权限验证。
如果有权限,就打开表继续执行。执行器会根据表的引擎定义,去使用这个引擎提供的接口。
相关问题
- 问:表T,没有k字段,执行下面语句时会报字段不存在的错误,这个错误是在哪个阶段报出来的呢?
select * from T where k = 1;
答:分析器。
《高性能mysql》里提到解析器和预处理器。
解析器处理语法和解析查询,生成一棵对应的解析树。
预处理器进一步检查解析树的合法,比如数据表、数据列是否存在,别名是否有歧义等。如果通过则生成新的解析树,提交给优化器。
词法解析、语法解析、语义解析(在语义解析这步做)
- 问:对于表的操作权限验证在哪里进行?
答:查询缓存、优化器之前的precheck、执行器
连接器从权限表里查询用户权限,并保存在变量里以供查询缓存、分析器、执行器在检查权限的时候使用
- 问:为什么要在执行器再次验证权限?
答:sql执行过程中可能会有触发器这种在运行时才能确定的过程,分析器工作结束后的precheck是不能对这种运行时涉及到的表进行权限验证的,所以需要在执行器阶段进行权限验证。