当前位置: 首页 > 科技观察

这么多年的增删改查,终于陷入了MySQL的架构设计

时间:2023-03-19 23:49:10 科技观察

目前,大部分后端开发者对MySQL的理解可能还停留在黑盒阶段。MySQL的基本使用没有问题,比如建库、建表、建索引,进行各种增、删、改、查。因此,很多后端开发者眼中的MySQL就是下图所示:在实际工作中遇到MySQL死锁异常、SQL性能不佳、异常报错等问题时,可以直接百度搜索。然后跟着博客解决,可能是我没看懂原理。为了解决这种知其然不知其所以然的问题,本文将带大家一起探秘MySQL的底层原理。这样当你遇到MySQL的一些异常或者问题时,可以直接找准本质,快速定位并解决。1、连接管理系统(客户端)在访问MySQL服务器之前,首先要做的是建立一个TCP连接。三次握手建立连接成功后,MySQL服务器对TCP传输的账号密码进行身份认证和权限获取。如果用户名或密码不正确,将收到一个Accessdeniedforusererror,结束客户端程序的执行;如果用户名和密码通过了认证,那么从权限表中会发现该账号所拥有的权限是与该连接关联的,此时后续的权限判断逻辑将依赖于读权限。那么我们来思考以下问题:一个系统会不会只与MySQL服务器建立一个连接?只能一个系统与MySQL服务器建立连接吗?当然不是,多个系统可以与MySQL服务器建立连接,而且每个系统都必须建立多个连接。因此,为了解决无限创建TCP和频繁创建和销毁TCP带来的资源耗尽和性能下降的问题。MySQL服务器中有专门的TCP连接池来限制连接数,采用长连接模式对TCP连接进行复用来解决上述问题。TCP连接收到请求后,必须分配给一个线程去执行,所以才会有一个线程池来经过下面的流程。我们将这些内容归纳到MySQL的连接管理组件中。因此,连接管理的职责就是负责认证、连接管理和访问权限信息。2、分析与优化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优化,生成执行计划根据执行计划调用存储引擎接口连接管理、解析和优化在Server层在MySQL架构中。3、总结在学习任何知识之前,不要急于求成细节,而是先了解大体脉络,形成全局观,然后再深入了解相关细节。MySQL架构分为Server层和存储引擎层。不涉及表数据读写的连接管理、解析和优化,都被划分到服务器层,而表数据的读写则交给存储引擎层。通过这个架构设计,我们发现server层其实是一个公共层,存储引擎层是一个多态层,可以根据需要选择具体的存储引擎。再想想,和模板方法设计模式是一模一样的。他们的执行过程是固定的。服务器层相当于公共模板函数,存储引擎层相当于抽象模板函数,可以按需子类实现。最后以一张MySQL的简化架构图结束本文。