MySQL实战 | 01-当执行一条 select 语句时,MySQL 到底做了啥?

也许,你也跟我一样,在遇到数据库问题时,总时茫然失措,想重启解决问题,又怕导致数据丢失,更怕重启失败,影响业务。

就算重启成功了,对于问题的原因仍不知所以。

本文开始,记录学习《MySQL实战45讲》专栏的过程。

也许有人会问,你记录有什么意义?直接看专栏不就行了吗?你这不是啃别人的剩骨头吗?

是的,这个系列,我只是基于专栏学习,但是我会尽量从我的角度搞懂每一个知识点,遇到不懂得也会将知识点进行拆分。

我知道关注公众号的小伙伴也有很多购买了这个专栏的,我希望大家都能够利用好这个机会,把 MySQL 吃透!

看大家的反馈情况吧,若有需要,可以建个小群,大家互相讨论学习!

下面开始正文。

大家或多或少都用过 MySQL,起码 select 还是会用的吧,但是 select 执行后,MySQL 内部到底发生了什么,你知道吗?

比如,我们有个简单的表 T,它有个 ID 字段,那么我们可以执行下面的语句

mysql> select * from T where ID=10;

语句执行很简单,但是具体到 MySQL 内部,其实是一个完整的执行流程。

MySQL 的基本架构

从下图就可以清楚地看出 MySQL 的命令执行流程:

MySQL 的基本架构

从该图可以看出,MySQL 主要分为 server 层和存储引擎层。

server 层中包含连接器,查询缓存,分析器,优化器,执行器,大多数核心功能以及内置函数,存储过程,触发器,视图等。

存储引擎层主要负责最终数据的存储和提取,例如常用的存储引擎 InnoDB、MyISAM 等。

好了,下面开始梳理一次完整的查询流程。

MySQL 执行流程

1 连接

首先通过连接器连接到数据库。

连接器的主要作用是建立连接,获取用户权限,维持连接,管理连接

连接的一般命令就是我们常用的登陆数据库的命令:

mysql -u$username -h$host -p$port -P

命令执行后,若用户名或者密码不对,或者数据库做了登录 ip 限制,都会收到异常信息。

若登陆成功,那么就代表连接成功建立。

之后连接器会维持当前连接,接下来连接器会查询出该用户的权限,后面所有的操作都会基于该权限,即使操作过程中有其他进程修改了该用户的权限。

连接完成后,若没有任何操作,连接就处于休眠状态,用命令 show processlist; 查看,就是 Sleep 状态的进程:

睡眠状态

当然,连接器不会让你一直握着连接不动,若休眠时间超过 wait_timeout(默认为 8 小时),则会断开当前连接。

若要再用,对不起,请重新连接~

长连接和短连接

其实这里的长短连接不是 MySQL 层面的概念。

长连接:长连接是相对于短连接来说的。长连接指在一个连接上可以连续发送多个数据包,在连接保持期间,如果没有数据包发送,需要双方发链路检测包。我理解 MySQL 默认的超时时间 8 小时,就属于一个长链接。

客户端连接--创建 socket 认证连接--维护连接--数据传输--维护连接--数据传输.....-关闭连接

短连接:是指通讯双方有数据交互时,就建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。

客户端连接--创建 socket 认证连接--维护连接--数据传输--关闭连接

长连接主要用于在少量客户端与服务端的频繁通信,因为这时候如果用短连接频繁通信常会发生 Socket 出错,并且频繁创建 Socket 连接也是对资源的浪费。

专栏中老师是建议使用长链接的,因为建立连接的过程比较复杂,应该尽量减少建立连接的动作。

长连接的管理

使用长连接后,随着连接数不断增加,会导致内存占用升高,因为 MySQL 在操作过程中会占用内存来管理连接对象,只有等到连接断开后才会释放。

如果连接一直堆积,就会导致内存占用过大,被系统强行杀掉,也就是会出现 MySQL 重启。

如何解决这个问题?

1、定期断开长连接;
2、MySQL 5.7+ 的版本中提供了 mysql_reset_connection 来重新初始化连接资源,这时不需要重新连接,就可以将连接恢复到刚刚创建完时的状态;

mysql_reset_connection

对于 mysql_reset_connection ,MySQL 官网的描述是这样的:

将连接重置,清空连接状态。
类似于重新连接,但是不会关闭当前连接,也不会进行重新鉴权。

会产生如下影响:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpjpjw.html