MySQL基础架构

MySQL基础架构

大体来说,MySQL可以分为 Server层存储引擎层 两部分。

  • Server层:涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等)
    • 所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
  • 存储引擎层:负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。

在这里插入图片描述

不同的存储引擎共用一个Server层,也就是从连接器到执行器的部分。

一、连接器 - 建立连接,权限认证

连接器:负责跟客户端建立连接、获取权限、维持和管理连接。

# 连接命令
mysql -h 127.0.0.1 -P 3306 -u root -p
# 本机登录(省略 -h ip -P port)
mysql -u root -p

密码也可以直接跟在-p后面写在命令行中,但这样可能会导致你的密码泄露,所以不建议。

连接命令中的 mysql 是客户端工具,用来跟服务端建立连接。

连接服务包含 本地socket通信 和 基于客户端/服务端工具实现的类似TCP/IP的通信。

  • 主要完成一些类似于连接处理、授权认证及相关的安全方案

该层引入了线程池的概念,为通过安全认证接入的客户端提供线程。

同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。

在完成TCP握手后,连接器开始进行认证:

  • 用户名密码错误,会收到一个 “Access denied for user” 的错误,然后客户端程序结束执行。
  • 用户名密码正确,连接器会到权限表查出你拥有的权限(之后这个连接的权限判断,都依赖于此时读到的)

这就意味着,一个用户成功建立连接后,即使修改了权限,也不会影响已经存在的连接,只有重新连接才会生效。

连接完成后,如果你没有后续的动作,这个连接就处于空闲状态(Command列显示为Sleep

# 查看连接列表
show processlist;

在这里插入图片描述

客户端如果太长时间没动静,连接器就会自动将它断开。这个时间由参数wait_timeout控制,默认值是8小时

  • 长连接:连接成功后,如果客户端持续有请求,则一直使用同一个连接。
  • 短连接:每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。

建立连接的过程通常是比较复杂的,因此在使用中要尽量减少建立连接的动作,也就是尽量使用长连接

全部使用长连接后,你可能会发现,有些时候MySQL占用内存涨得特别快

MySQL在执行过程中,临时使用的内存是管理在连接对象中的,这些资源在连接断开的时候才会释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是MySQL异常重启了。

怎么解决这个问题呢?可以考虑以下两种方案。

  • 定期断开长连接。使用一段时间,或程序里面判断执行过一个占用内存的大查询后,断开连接,之后再重连。
  • 如果用的是MySQL 5.7或更新版本,可以在每次执行一个比较大的操作后,执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

二、查缓存 - 提高效率

执行过的语句及其结果可能会以key-value的形式,被直接缓存在内存中。key是查询语句,value是查询结果。

select * from T where ID=10;

MySQL拿到一个查询请求后,会先查询缓存,如果查询命中缓存就直接返回结果,否则继续执行后面的操作。

查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此:

  • 不推荐用缓存查询:更新频繁的表
  • 推荐使用缓存查询:静态表,很长时间才会更新一次

可以将参数 query_cache_type 设置成 DEMAND,默认不查询缓存。也可以通过查询的时候手动指定,如下:

# 查询缓存
select SQL_CACHE * from T where ID=10;
# 不查询缓存
select SQL_NO_CACHE * from T where ID=10;

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

三、分析器 - 做什么

如果没有命中缓存,就开始真正执行语句了。首先,MySQL需要知道你要做什么,因此需要对SQL语句做解析。

  • 先做 词法分析:解析 SQL语句 字符串的含义(查询/更新?表名/列名?表/列是否存在?)
  • 再做 语法分析:判断 SQL语句 是否符合 语法规则。

四、优化器 - 怎么做

经过了分析器,MySQL就知道你要做什么了。在开始执行之前,还要先经过优化器的处理。

  • 在表里面有多个索引的时候,决定 使用哪个索引
  • 在一个语句有多表关联(join)的时候,决定 各个表的连接顺序

优化器阶段完成后,SQL语句的执行方案就确定下来了。

五、执行器 - 执行语句

进入执行器阶段,开始操作引擎,执行语句:

  • 先判断对表T有没有执行查询的权限。如果没有,就返回没有权限的错误。
  • 如果有权限,就打开表继续执行。执行器就会根据表T的引擎定义,去调用对应引擎提供的接口

对于下面的语句,分析执行器的执行流程:

select * from T where ID=10;
  • 调用InnoDB引擎接口,“取第一行”,判断ID值是不是10,如果是,则将这行存在结果集中,不是则跳过
  • 调用InnoDB引擎接口,“取下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
  • 执行器将 上述遍历过程中 所有满足条件的行 组成的记录集 作为结果集返回给客户端。

对于有索引的表,执行的逻辑也差不多:

  • 第一次调用 “取满足条件的第一行” 这个接口。
  • 之后循环调用 “取满足条件的下一行” 这个接口。

在数据库的慢查询日志中有一个rows_examined的字段

  • 表示这个语句执行过程中扫描了多少行。这个值就是在执行器每次调用引擎获取数据行的时候累加的。

注意:rows_examined ≠ 引擎扫描行数(某些场景下,执行器调用一次,在引擎内部会扫描多行)

六、存储引擎

存储引擎层真正的负责了MySQL中数据的存储和提取,服务器通过API和存储引擎进行通信。不同的存储引擎具有不同的功能,这样我们可以根据自己的需要,来选取合适的存储引擎。

1、存储引擎的概述

​ MySQL中的数据用各种不同的技术存储在文件或内存中,包括存储方式、索引技巧、锁定水平等不同功能。这些不同的技术以及配套的功能被称作存储引擎。

​ Oracle,SqlServer等数据库只有一种存储引擎。MySQL提供了插件式的存储引擎架构(多种存储引擎)。 所以MySQL可以根据需要使用相应引擎,或者编写存储引擎。

​ MySQL 常用的存储引擎有三种: InnoDB 、MyISAM 、MEMORY。创建表时如果不指定存储引擎,系统就会使用默认的存储引擎, MySQL5.5之前 默认是MyISAM,MySQL5.5之后就改为了InnoDB

2、存储引擎的对比

特点 InnoDB MyISAM MEMORY
存储限制 64TB
事务安全 支持
锁机制 行锁,表锁 表锁 表锁
外键 支持
BTree索引 支持 支持 支持
Hash索引 支持
全文索引 支持(5.6版本后) 支持
集群索引 支持
数据索引 支持 支持
索引缓存 支持 支持 支持
数据可压缩 支持
空间使用 N/A
内存使用 中等
批量插入速度

3、存储引擎的命令

-- 查看数据库支持的存储引擎
show engines;

-- 查询某个数据表的存储引擎
show table status from 数据库名 where name = '数据表名';

-- 创建表时指定存储引擎
create table 表名(
	列名 数据类型 约束,
	...
) engine = 存储引擎名;

-- 修改数据表的存储引擎
alter table 表名 engine = 存储引擎名;

-- 设置默认存储引擎
set default_storage_engine = <存储引擎名>

4、存储引擎的选择

# InnoDB(MySQL5.5之后默认的存储引擎)
1. 优点:
		1)InnoDB 提供了具有提交、回滚、崩溃恢复能力的事务安全。
		2)InnoDB 采用行锁,适合处理并发写操作。
2. 缺点:
		会占用更多的磁盘空间以保留数据和索引
3. 场景:
		1)对事务的完整性和安全性有比较高的要求。
		2)在并发条件下要求数据的一致性,写多读少。

# MyISAM(MySQL5.5之前默认的存储引擎)
1. 优点:
		1)MyISAM 内存要求低,节约资源。
		2)MyISAM 采用表锁,读取速度快,查询效率高
2. 缺点:
		1)不支持事务和外键操作
		2)不适合并发写操作
3. 场景:
		1)对事务的完整性、并发性要求不是很高。
		2)以查询操作为主,只有很少的更新和删除操作,读多写少
		
# MEMORY
1. 特点: 
		将所有数据保存在内存中,在需要快速定位记录和其他类似数据环境下,可以提供更快的访问。
2. 使用场景:
		通常用于更新不太频繁的小表,用以快速得到访问结果。

相关推荐

  1. MySQL 架构

    2024-03-17 05:18:06       18 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-17 05:18:06       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-17 05:18:06       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-17 05:18:06       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-17 05:18:06       18 阅读

热门阅读

  1. Python列表详解

    2024-03-17 05:18:06       19 阅读
  2. 【C语言】打印1-100之间所有3的倍数的数字

    2024-03-17 05:18:06       19 阅读
  3. 使用API删除Gitlab Pipeline

    2024-03-17 05:18:06       19 阅读
  4. CSS2DObject 形成3D模型二维屏幕平面label

    2024-03-17 05:18:06       17 阅读
  5. Hive Sql获取含有特殊字符key的json数据

    2024-03-17 05:18:06       21 阅读
  6. LeetCode 395. 至少有K个重复字符的最长子串

    2024-03-17 05:18:06       15 阅读