本文转载自微信公众号《编程阿兴》,作者编程阿兴。转载本文,请联系程序员阿星公众号。前言目前,大部分后端开发者对MySQL的理解可能还停留在黑盒阶段。MySQL的基本使用没有问题,比如建库、建表、建索引,进行各种增、删、改、查。在很多后端开发者眼中,MySQL就是下图所示。实际工作中遇到MySQL死锁异常、SQL性能不佳、异常报错等问题,可以直接百度搜索。然后跟着博客解决,可能是我没看懂原理。为了解决这种知其然不知其所以然的问题,阿星再学MySQL系列文章将带你全方位探究MySQL的底层原理。这样当你遇到MySQL的一些异常或者问题时,可以直接找准本质,快速定位并解决。在连接管理系统(客户端)访问MySQL服务器之前,首先要做的是建立一个TCP连接。三次握手建立连接成功后,MySQL服务器对TCP传输的账号密码进行身份认证和权限获取。如果用户名或密码不正确,将收到用户错误拒绝访问。客户端程序完成用户名和密码认证后,会从权限表中查到该帐号的权限与连接相关联。后续的权限判断逻辑会依赖于此时读取的权限,我们想一个问题。一个系统只能与MySQL服务器建立一个连接吗?只能一个系统与MySQL服务器建立连接吗?当然不是,多个系统可以与MySQL服务器建立连接,每个系统必须建立多个连接。因此,为了解决无限创建TCP和频繁创建和销毁TCP带来的资源耗尽和性能下降的问题。MySQL服务器中有专门的TCP连接池来限制连接数,采用长连接模式对TCP连接进行复用来解决上述问题。TCP连接收到请求后,必须分配给一个线程去执行,所以才会有一个线程池来经过下面的流程。我们将这些内容归纳到MySQL的连接管理组件中。因此,连接管理的职责就是负责认证、连接管理和访问权限信息。解析和优化都经过了连接管理,现在MySQL服务器已经拿到了SQL字符串。如果是查询语句,MySQL服务器会使用selectSQL字符串作为key。去缓存中获取,命中缓存,直接返回结果(返回前需要授权验证),未命中则执行后续阶段。此步骤称为查询缓存。需要注意的是,selectSQL字符串必须完全匹配,任何不同都会导致缓存不命中(空格、注释、大小写、一些系统函数)。Tips:虽然查询缓存有时可以提高系统性能,但也不得不为维护这个缓存造成一些开销。从MySQL5.7.20开始,不再推荐查询缓存,MySQL8.0将删除。如果没有命中缓存,或者非selectSQL进入analyzer阶段。由于系统只发送一个文本字符串,MySQL服务器需要根据SQL语法解析文本。如果您的SQL字符串不符合语法规范,您将收到一个YouhaveanerrorinyourSQLsyntax错误提醒。通过分析器后,说明SQL字符串符合语法规范,此时MySQL服务器即将执行SQL语句。MySQL服务器应该如何执行?你需要生成一个执行计划,交给MySQL服务器执行,这样就到了优化器阶段。优化器不仅仅是生成一个执行计划那么简单,它会在这个过程中帮助你优化SQL语句。比如外连接转内连接、表达式简化、子查询转连接、连接顺序、索引选择等,优化的结果就是执行计划。到现在为止,我还没有真正读写过真正的表,只是产生了一个执行计划。于是进入了executor阶段,MySQL服务器最终执行了SQL语句。在开始执行的时候,首先要判断自己是否对这张表有相应的权限。如果不是,将返回权限错误。如果有权限,调用存储引擎API,按照执行计划读写表。存储引擎API只是一个抽象的接口,下面还有一个存储引擎层。具体实现取决于表选择的存储引擎。说起来,上面提到的querycache、analyzer、optimizer、executor都可以归纳为MySQL的分析优化组件。因此,解析优化的职责如下:缓存SQL语法解析验证SQL优化,生成执行计划根据执行计划调用存储引擎接口。连接管理、解析和优化都在MySQL架构的Server层。小结在学习任何知识之前,不要急于求细节,而是先了解大体脉络,有全局观,再深入相关细节。MySql架构分为Servce层和存储引擎层。不涉及表数据读写的连接管理、解析、优化组件被划分到Servce层,表数据的读写交给存储引擎层。通过这个架构设计,我们发现Servce层其实是一个公共层,而存储引擎层是一个多态层,具体的存储引擎是按需选择的。再想想,和模板方法设计模式是一模一样的。他们的执行过程是固定的。Servce层相当于公共模板功能,存储引擎层相当于抽象模板功能,可以按需子类实现。阿星最后以一张MySQL的简化架构图结束本文,我们下期再见~
