用了这么久的MySQL,你了解MySQL的架构吗?

前言

数据库大家都清楚吧,目前市面上主流的数据库分为Oracle、MySQL、SQLServer。SQLServer微软家开发的,我想.Net开发用的多,我们大学数据库课程所使用的数据库,安装很头疼当时还重装了系统,考完试第一件事就是把它卸载了,所以不是那么熟。Oracle作为排名第一的数据库,很遗憾我也只是学过,并没有再实际开发中用过这玩意,所在的公司都是清一色的MySQL。所以我对MySQL比较熟一点,所以我会以MySQL作为主要案例来讲解。其他同学可能就失望了,但是知识应该都是相通的,并不影响我们去了解数据库。

MySQL架构

MySQL为了能让在各种环境中都发挥最大的作用,将它的架构分为了Server层和存储引擎层。处理和存储分离的这种设计,可以让我们在使用的时候根据不同场景来选择最佳的存储方式。

连接器

要操作数据库,首先需要和数据库建立连接。当客户端发起一个建立连接的请求,连接器需要账号校验、权限校验,维持并且管理这个链接。

首先会校验你的账号密码是否正确,如果不正确,那么此时和客户端的链接就已经结束了。如果账号密码通过校验,接下来就会获取你的权限表。

查看连接状态

这个时候我们已经和MySQL链接建立完成,这时候如果你没有做后续操作,此时我们的链接就是空闲状态,我们可以使用show processlist查看链接状态。

如果客户端连接上后,如果你长时间没有操作(默认8小时,通过wait_timeout参数控制),那么此时连接就会自动断开。这时候你如果再次发生请求就会收到“Lost connection”这个错误了,所以你想继续就需要重连。

连接的建立过程通常是一个重量级操作,我们应该尽可能的减少建立连接的操作。这时候我们可以使用长连接,使用长连接过后,如果客户端持续有请求,那么就一直使用同一个连接。

使用长连接后又会面临一个问题,那就是内存会飙升的很快,主要是MySQL在执行过程中临时使用的内存是管理在连接对象里面的。长时间积累下来就会导致内存占用太大,而这些资源只会在断开连接的时候释放,那么最终就会导致OOM(Out Of Memory)被系统kill掉,然后MySQL就会重启。这种情况在JVM里面就是频繁的Full GC。

如何解决OOM

1:定期断开长连接,或者程序里判断一下当执行过一个占用内存比较大的查询后就断开连接,下次使用后再重新连接。都是依靠断开连接时候会释放内存,但是还是会出现频繁建立的问题。

2:当你的MySQL是5.7以上的版本后,你可以在每次执行一个比较大的操作后执行mysql_reset_connection初始化连接资源,让连接恢复到刚创建完的状态。

查询缓存

连接建立完成后,如果我们开启了查询缓存这个功能,这时候会先去缓存看看之前是不是执行过这个语句(注意:此时并不会进行语义分析)。被缓存的信息是以kay-value的形式存放在内存中,key是我们的查询语句,value就是结果集。

如果缓存命中结果就会直接返回给用户,不需要再走下面的步骤了。

看似美好但是却是非常脆弱的,查询缓存的失效非常频繁,以至于我们只要对一个表进行更新操作,这个表上所有的查询缓存就会被清空。可能我们缓存刚存起来,还没使用就因为一个更新操作全部清空了,这样就会使得查询缓存命中率非常低。

但是如果你有一张表很长时间才会更新一次,或者永远都不会更新,例如每年年初的时候生成的年度账单。那么针对这类表开启查询缓存比较适合。

不过MySQL8.0后移出了查询缓存,所以这一块的知识请你忘记吧~

分析器

如果没有命中缓存,这时候就开始执行语句了,首先需要看看你写的语句有没有语法错误。

首先进行“词法分析”,你的语句有很多单词、空格MySQL需要知道你想干什么。例如读取到select就知道这是一个查询语句,from user就知道字符串user对应user表,

做完这些后,就需要进行“语法分析”,根据词法分析的结果判断你写的SQL是不是有语法错误,列如select写成了elect,如果语法不对这时候就会给你提示你有语法错误,并告诉你再哪一行附近发生了错误。

优化器

如果到这一步,那么恭喜你MySQL已经知道你要做什么了。但是再开始执行语句之前还要经过优化器的处理。

优化器的作用就比较好理解了,我们建表的时候会创建很多的索引,优化器要做的事情就是使用哪个索引、这么多的条件先查那个表、如果要排序应该怎么处理。会有很多个方案,最后由优化器决定选用哪个方案。

需要注意的一点就是MySQL选出的最优是执行成本最低的模型,并不是执行时间最短的模型。

执行器

如果说分析器是让MySQL知道你要做什么,优化器是怎么做,那么执行器就开始具体进行操作。

执行器这里首先会根据第一步我们拿到的权限表,判断我们将要操作的表是不是有权限。如果通过的话执行器就根据表的引擎定义,使用这个引擎提供的接口完成操作,然后返回数据。

 

最后,如果感觉对你有帮助就来个二连吧:关注、点赞!

猜你喜欢

转载自blog.csdn.net/qq_25448409/article/details/105334642
今日推荐