MySQL基础架构详解

概述

我们学习东西,都不应该是先去了解细节,而是应该窥其全貌,这样才能从高纬度去理解问题,同样我们学习mysql也是一样的,我们应该先了解整个mysql架构,及来龙去脉,才能更好的掌握它。下面我们开始深入浅出的方式了解mysq基础架构知识。

SQL执行的来龙去脉

我们学习MySQL的时候,会编写SQL语句,如 select * from T where id=0这里查询T表,条件ID等于0。当我们执行这条SQL语句的时候,返回一个结果,却不知道这条SQL语句在MySQL里面的执行流程。如果我们深入去了解这个条SQL的执行过程,我们会发现MySQL在执行SQL过程中会经历非常多步骤,每一个步骤都有大量的功能支持,下面我们一一拆解这些功能,把它当成一辆完成的车一样,将零部件一件件拆解下来,深刻认识这些零件,让我们深入理解这些零件在MySQL所体现的作用。

SQL执行流程图

连接器

在使用MySQL的时候,用户会先对MySQL进行连接,在这时我们直面的第一个零件就是连接器,连接器负责和客户端建立连接,获取权限,维持和管理连接。连接命令 mysql -h ір − P ір -P ір−Pport -u$user -p执行完命令后,则建立连接,这个建立连接过程中会进行经典的TCP握手交互,之后认证身份,认证成功后会验证当前用户的权限,用于之后这个连接里面的权限判断逻辑,都会依赖此时读到的权限。

当我们建立连接后,我们可以使用show processlist 查看所有连接情况,当command 列显示为 "Sleep"时说明这个行记录是空闲连接。

如果当前连接的客户端太长时间没有活跃,连接器将会自动断开,这个时间,我们可以通过wait_timeout 控制,这个参数默认是8小时。

如果连接被断开之后,客户端再次发起请求连接,会收到一个错误提醒:Lost connection to MySQL server during query。如果这个时候你看到这个信息,想要继续操作,则需要重新连接,才能继续执行。长连接在数据库里面使用,长连接是指当客户端连接成功后,如果客户端有持续请求,则会一直使用这个连接。短连接在数据库使用,短连接是指客户端连接成功后,客户端使用一次这个连接后,这个连接就会关闭,如果下次需要连接则需要重新创建短连接,这个创建连接的成本是很高的,所以一般在数据库中建议使用长连接,避免频繁创建连接,浪费资源。当时使用长连接也会造成一些问题,如,如果大量连接创建后,我们会观察服务器内存,会发现内存占用较高,因为创建大量连接会导致系统内存占用过高,此时还可能经历被系统杀掉(OOM),从而出现MySQL服务重启的现象。
怎么解决长连接带来的问题呢,有两种方案如下?

● 定期断开长连接,避免大量无用连接而占用内存。在使用一段时间内,在程序里面判断一个占用内存的查询,断开连接,之后要查询在重新连接。

● 如果使用的MySQL5.7 或者比5.7更新的版本,可以在执行一次占用内存较大的操作后,通过执行mysql_reset_connection来重新初始化连接资源,这个过程不需要重连和重新做权限验证,但是这个操作会讲连接恢复到刚刚连接时的状态。

查询缓存(mysql8已经废弃)

建立连接后,开始执行SQL语句,执行逻辑会先查询缓存。MySQL拿到一个查询请求后, 会先到查询缓存看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以key-value对的形式, 被直接缓存在内存中。 key是查询的语句,value是查询的结果。如果你的查询能够直接在这个缓存中找到key, 那么这个value就会被直接返回给客户端。

但是大多数情况下我会建议你不要使用查询缓存,为什么呢?因为查询缓存往往弊大于利。

查询缓存的失效非常频繁, 只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来, 还没使用呢, 就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。

比如,一个系统配置表,那这张表上的查询才适合使用查询缓存。MySQL也提供了这种"按需使用"的方式。你可以将参数query_cache_type设置成 DEMAND,这样对于默认的SQL语句都不使用查询缓存。而对于你确定要使用查询缓存的语句,可以用SQL_CACHE显式指定,像下面这个语句一样:select SQL_CACHE * from T where ID=10;

MySQL 8.0版本直接将查询缓存的整块功能删掉了, 8.0开始彻底没有这个功能了。

分析器

如果没有命中缓存,则会进行执行SQL环节,在到真正执行SQL语句前,会进行SQL语句分析,然后对SQL语句的解析。而分析器又被称为"词法分析器",你输入的是由多个字符串和空格组成的一条SQL语句,MySQL需要识

别出里面的字符串分别是什么,代表什么。做完了这些识别以后, 就要做"语法分析"。根据词法分析的结果, 语法分析器会根据语法规则,判断你输入的这个SQL语句是否满足MySQL语法。

优化器

经过了分析器, MySQL就知道你要做什么了。 在开始执行之前,还要先经过优化器的处理。优化器是在表里面有多个索引的时候,决定使用哪个索引,或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。

执行器

开始执行的时候, 要先判断一下你对这个表T有没有执行查询的权限,如果没有,就会返回没有权限的错误,执行器调用一次。 如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引

擎提供的接口,在引擎内部则扫描了多行, 因此引擎扫描行数跟rows_examined并不是完全相同的。

相关推荐
人才程序员24 分钟前
【C++拓展】vs2022使用SQlite3
c语言·开发语言·数据库·c++·qt·ui·sqlite
极客先躯34 分钟前
高级java每日一道面试题-2025年01月23日-数据库篇-主键与索引有什么区别 ?
java·数据库·java高级·高级面试题·选择合适的主键·谨慎创建索引·定期评估索引的有效性
指尖下的技术40 分钟前
Mysql面试题----MyISAM和InnoDB的区别
数据库·mysql
永远是我的最爱1 小时前
数据库SQLite和SCADA DIAView应用教程
数据库·sqlite
指尖下的技术2 小时前
Mysql面试题----为什么B+树比B树更适合实现数据库索引
数据结构·数据库·b树·mysql
Ciderw2 小时前
MySQL为什么使用B+树?B+树和B树的区别
c++·后端·b树·mysql·面试·golang·b+树
数据馅2 小时前
python自动生成pg数据库表对应的es索引
数据库·python·elasticsearch
峰子20122 小时前
B站评论系统的多级存储架构
开发语言·数据库·分布式·后端·golang·tidb
胡耀超3 小时前
CentOS 7.9(linux) 设置 MySQL 8.0.30 开机启动详解
linux·mysql·centos
浏览器爱好者3 小时前
如何使用MongoDB进行数据存储?
数据库·mongodb