1. 概述
不管是开运、运维、测试,都或多或少的要接触MySQL,了解MySQL的基础架构及各个组件之间的关系,有助于我们更加深入的理解MySQL,下面由一张MySQL基础架构图来一起走进MySQL。
MySQL可以基本划分为Server层和存储引擎层两部分:
Server层包含了MySQL大多数核心功能,除了图中标注的连接器,查询缓存,分析器,优化器,执行器,还有所有的内置函数(日期,时间,数学和加密函数),所有跨存储引擎的功能都在这一层实现,如存储过程、触发器、视图等。
存储引擎层负责MySQL中数据的存储和提取。和Linux下的各种文件系统一样,每个存储引擎都有自己的优势和劣势,各种存储引擎通过提供API和Server层对接,通过API屏蔽各种存储引擎之间的差异。常见的存储引擎有InnoDB、MyISAM、Memory,现在最常用的是InnoDB,也是从MySQL5.5版本开始成为默认的存储引擎,在5.5之前默认的是MyISAM
2. 连接器
连接器是MySQL Server层的第一个模块,也是处理客户端请求的模块,连接器负责跟客户端建立连接、获取权限、维持和管理连接。
- 登录命令
mysql -h$ip -P$port -u$user -p
# 或者
mysql -h$ip -P$port -u$user -p$password
- 如果账号密码错误,会提示:Access denied for user
如果登录认证通过,会查询当前用户下的权限,之后用户的任何操作都是在这个权限范围内,即使你用管理员账号对这个用户的权限做了修改,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置。
3. 查询缓存
查询缓存在 MySQL5.7.20 版本已过时,在 MySQL8.0 版本中被移除,这里作为了解即可。
MySQL 查询缓存存储客户端请求的查询结果信息( SELECT 语句)。MySQL 服务器在接收到相同的请求时,会直接将查询缓存中的结果返回给客户端,不再去数据库中重新查询。而且,查询缓存是在多个会话中共享的,一个客户端的查询缓存结果可以被另一个客户端的相同请求复用,从而加快了查询效率。
缓存以key-value的形式存储,存放在一个引用表中,key是通过一个哈希值的引用,这个哈希值包括查询本身(sql),当前要查询的数据库,客户端协议的版本等一些其他会影响返回结果的的信息;查询结果作为value(任何字符上的变化,例如空格,注释都会导致缓存不命中)。
如果表被更改,所有的缓存都将失效,表的更改是指数据的改变和表结构的改变,包括INSERT、UPDATE、 DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE等。
对于数据经常变更的数据库来说,缓存命中率是很低的,这时查询缓存就是弊大于利,所以不建议使用缓存;而对于那些长时间不变、查询频率很高的数据,可以采用Redis缓存。
4. 分析器
我们根据MySQL语法编写一条SQL语句交给Server层以后,分析器会对SQL进行词法分析和语法分析。
已如下SQL为例:
select id,name from `tab`;
- 词法分析
SQL语句是由多个字符串和空格组成的,MySQL的分析器需要识别里面的字符串分别是什么,代表什么。
MySQL从 "select" 关键字分析出这是一个查询语句,把字符串识别成 "tab" 表 'tab',把字符串 "id,name" 识别成列 'id','name'。
- 语法分析
根据词法分析的结果,语法分析器会根据语法规则,判断你输入的SQL语句是否满足MySQL语法。
mysql> elect id,name from tab;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'elect id,name from tab' at line 1
一般语法错误会提示第一个出现错误的位置,所以你要关注的是紧接 "use near" 的内容。
5. 优化器
经过分析器生成的语法树被认为是合法的,交由优化器转化成执行计划。
MySQL判断出了一条SQL语句要做什么之后,对其进行各种优化,包括重写查询语句、选择合适的索引、表的读取顺序等等。
MySQL的优化器是基于成本的优化,尝试预测一个查询使用某种执行计划的成本,进而选择最小的那个。例如:表中有多个索引的时候决定使用哪一个、使用联合索引的时候根据索引调整where条件的顺序、多表关联(join)的时候,决定各个表的连接顺序等等。
如果想知道优化器是怎么进行优化决策的,可以通过explain获取优化的信息,explain具体的使用和解释后面章节会说明的。
6. 执行器
语句经过优化后,就要进入执行阶段,开始执行的时候,要先判断权限,如果没有,就返回没有权限的错误。如果有权限,就调用存储引擎的API操作数据。
7. 总结
用一条SQL语句的执行过程来总结一下:
去数据库连接池中获取一条数据库连接;
获取连接后把SQL语句发给数据库服务;
数据库服务负责监听网络事件接收到消息后交给SQL接口,SQL接口基于通信协议解析出SQL语句;
将解析出来的语句交给SQL解析器,解析出SQL语句要做的事情并提供所有方案;
查询优化器根据解析出的信息,优化出最佳的查询路径;
将优化后的查询路径交给SQL执行器去执行;
执行器调用存储引擎接口执行最优路径;
存储引擎在被执行器调用的过程中负责去访问内存和磁盘完成数据的更新等操作。