MySQL的内部模块与sql语句的执行流程之路

  以前每天都在用mysql,但是底层具体是怎么运行,以及在数据库优化真的是两眼一抹黑,这几天偶尔看了一下沽泡学院青山老师讲的课程,总算是了解了一些,我不是打广告,只是想着听了自己再总结一下,记忆会更深刻一些,下面用的图,也都是截屏的,我自己就不整理了,因为已经很详细了。

 首先我们在从客服端写一条查询的sql向MySQL服务端查询数据时,主要经过下面的步骤,如图

MySQL的内部模块与sql语句的执行流程之路

 

      因为数据是存储在MySQL服务端的,所以在客户端获取数据的第一步是建立连接;

建立连接就需要有通信协议,一般通信协议类型有两种 :1、同步 ;2、异步

 一般来说客户端连接服务端的通信协议类型是同步连接(具体我也不太清楚为什么,等后面我研究明白了,再解释一下),既然是连接,那连接方式也是有区别的,MySQL支持短连接和长连接,一般来说MySQL用的都是长连接,会把这个连接放入客户端的连接池。

通信方式: 

MySQL的内部模块与sql语句的执行流程之路

MySQL使用的通信方式是半双工,在一次连接中,要么是客户端向服务端发送数据,要么是服务端向客户端发送数据,不可能两者同时出现,所以在客户端向服务端发送sql语句时,不能分割发送,不管sql语句多大,都是一次发送,这样在大批量插入数据时,会出现问题。

 

   现在我们说一下一个sql语句进入到MySQL服务端具体是怎么运行的,当sql语句通过连接接口进入Server层时,首先会查询缓存,因为在MySQL中的查询缓存限制调节太过苛刻,5.7版本及以前是默认关闭的,8.0版本已经移除。原有是首先它要求sql语句必须完全一致,英语的大小写,空格的多少都会是缓存失效,且数据库里面的数据只要有一个变动,也会使原有的缓存失效。缓存这里,一般是还专业的事情交给专业人士处理,一般是交给ORM框架,或者Redis等等。

    当我们写一个sql语句时,如果错误,会提示一个1064给我们,MySQL是怎么知道我们的语句写错了?

这里就用到第一张图的解析器(Parser)和预处理模块(Preprocessor), 这里主要对sql语句进行词法、语法和语意的分析,处理。词法分析就是将sql语句分割成一个个单词,语法分析就是将上面分好的单词,一个个按照sql语法规则对号入座的放入到解析器对应的位置中,根据语法规则生成一个数据结构,这里我们把它叫解析树(select_lex)。

MySQL的内部模块与sql语句的执行流程之路

     如果我们写的sql语句不能按照sql语法规则生成这样的解析树,哪里错误就会提示1064反馈给我们,这也是sql报错为什么会告诉我们错误位置的原因。

     在词法,语法都没有错误后,会进行解析预处理,假如表名或者字段名不存在错误,都是在这里进行分析处理的,所以,假如一个sql语句的表名或者字段名不存在,报错是在解析时,解析sql环节的预处理阶段报错。再解析全部正确后,会生成一个新的解析树。

     生成的新的解析树会进入下一个环节,也就是优化器(Optimizer),解析树是一个可以被执行器认识的数据结构,在这里需要强调一个问题,那就是一条sql语句不止一种执行方式,最终执行器执行的执行语句也不一定是最初客户端发送的sql语句,因为在执行器执行sql语句前要经过一个优化模块(Optimizer),优化器的目的就是根据解析树生成不同的执行计划(Execution plan),然后选择最优的执行计划,选择规则是,谁开销(cost)最小选择谁。

    当优化器将解析树变成一个执行计划(Execution-plans),执行计划也是一种数据结构,执行器根据执行计划调用引擎接口,到存储引擎层查找数据。

 

   存储引擎

      表在存储数据的同时,还要组织数据的存储结构,这个存储结构就是由我们的存储引擎决定的,所以也可以把存储引擎叫做表类型。

       MySQL支持多种存储引擎,它们可替换,所以叫做插件式的存储引擎。MySQL支持的存储引擎类型如下,现在主要用InnoDB。

       MySQL的内部模块与sql语句的执行流程之路

  

InnoDB :  1、支持事务,支持外键,因此事务的一致性,完整性高。

                 2、支持行级别的锁和表级别的锁。

                 3、支持读写并发,写不阻塞读(MVCC)  

                 4、特殊的索引方式,可以减少IO,提升查询效率。

    适合:经常更新的表,存在并发读写或者有事务处理的业务系统。

其他的存储引擎及特性,我下次再分出来详细说一下。

 

执行引擎,返回结果:

 执行器,或者叫执行引擎,它利用存储引擎提供的API来完成操作,最后把数据返回给客户端,即使没有结果也要返回。

 

                                                                       MySQL 体系结构总结

如下图,(图是我剪切的额,凑合着看)

MySQL的内部模块与sql语句的执行流程之路

1、Connector : 用来支持各种语言和SQL的交互,如PHP,Python,java 的JDBC;

2、Management Services & Utilities : 系统管理和控制工具,包括备份恢复、MySQL复制、集群等。

3、Connection pool : 连接池,管理需要缓冲的资源,包括用户密码,权限,线程等等。

4、Sql Interface : 用来接收用户的SQL命令,返回用户需要的查询结果。

5、Parser : 解析器,用来解析SQL语句。

6、Optimizer : 查询优化器,优化解析器传来的解析树(数据结构),优化出执行计划(数据结构)。

7、Cache and Buffer : 查询缓存,除了行记录的缓存外,还有表缓存,Key缓存,权限缓存等等。

8、Pluggable Storage Engines :  插件式存储引擎,它提供API给服务层用,跟具体的文件打交道。

 

                                                                                      架构分层

 

总体,可以把MySQL分成两层,执行操作的服务层(Server),和存储管理数据的存储引擎层

MySQL的内部模块与sql语句的执行流程之路

服务层:包括客户端跟服务端的连接,查询缓存的判断,对SQL语句进行词法,语法的解析(比如关键字怎么识别,别名怎么识别,语法有没有错误等等),

然后就是优化器,MySQL底层会根据一定的规则对我们的SQL 语句进行优化,最后再交给执行器去执行。

存储引擎层:存储引擎就是我的数据真正存放的地方,再MySQL里面支持不同的存储引擎,再往下就是文件管理系统,内存或者磁盘。