mysql总体上分为server层和存储引擎层
server层负包括连接器、缓存、解析器、优化器、执行器
存储引擎层则负责存储数据
连接器
连接器负责跟客户端建立连接、获取权限、维持和管理连接。
它首先会判断请求的账号和密码是否正确,如果不正确则返回 ”Access denied for user”的错误,当账户验证成功后,连接器会去权限表中查询该用户的权限,该连接随后所有操作的权限都与此次查询的权限有关(即使修改了用户的权限,这条连接的权限还是获取时的权限,只有下次建立新的连接才会修改)
通过 show processlist
可以查看当前的连接以及其状态,当连接超过 8 小时没有进行任何的操作就会断开连接,时长可以通过 wait_timeout
控制
一个连接的连接时间过长可能会导致 mysql 发生 OOM,因为一个连接所占用的内存只有在断开时被清理,所以我们可以通过以下方法解决
- 定期断开连接,直到下次需要进行操作时再重新创建连接
- mysql5.7 之后的版本可以运行
mysql_reset_connection
来将所有连接恢复到初始的状态
缓存
当一条查询请求到达后,会先到查询缓存中查找是否存在缓存,缓存以 key-value 的形式存储,key 为 sql 语句,value 为查询结果
通常不建议使用查询缓存,因为其弊大于利:
查询缓存的失效非常的频繁,一张表的缓存会在这张表更新时全部删除,这就可能导致了一个缓存还没有被使用就被删除了,这样频繁更新的表的缓存命中率就会很低
在 mysql8.0 后查询缓存的模块就被删除了
解析器
如果缓存没有命中就会进入解析器,解析器会对 sql 语句进行 “词法分析” 和 “语法分析”
词法分析会将 sql 语句中每个单词的含义分析出来,如:select 代表查询关键字、T 对应数据库中一张表
语法分析则会判断这条 sql 语句是否满足语法要求
优化器
如果解析器判断 sql 语句没有问题就会进入优化器,优化器顾名思义就是对 sql 语句进行优化
mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
上述语句有两种方案:
-
先找到 t1 中 c=10 的数据,之后根据 id 进行联合,再找到 t2 中 d=20 的数据
-
先找到 t2 中 d=20 的数据,之后根据 id 进行联合,再找到 t1 中 c=10 的数据
这两种方案的执行效果相同,但是最终的执行时间不一定相同,优化器的作用就是找到执行的方案和选择索引
经过优化器后 sql 的执行方案就被确定下来了
执行器
执行器会根据前面的结果执行语句
执行前会进行权限的判断是否有对该表的权限,如果没有就会报错
如果有权限就会根据执行方案和选择的索引执行相应的语句,不同的表有不同的引擎,这里会调用相应引擎的接口去执行