目的:了解 SQL执行流程 以及 MySQL 内部架构,每个零件具体负责做什么
- 理解整体架构
- 分别有什么模块
- 每个模块具体做什么
目录
1 服务器处理客户端请求
1.1 MySQL 服务器端逻辑架构说明
2 Connectors
3 第一层:连接层
3.1 数据库连接池(Connection Pool)
4 第二层:服务层
5 第三层:存储引擎层
6 存储层 — 文件系统(不属于 MySQL 架构)
6.1 日志模块
6.2 数据模块(数据的文件存储格式)
1.7 架构总结
巩固知识
1 服务器处理客户端请求
1.1 MySQL 服务器端逻辑架构说明
2 Connectors
Connectors,指的是不同语言中与SQL的交互。MySQL首先是一个网络程序,在TCP之上定义了自己的应用层协议。所以要使用MYSQL,我们可以编写代码,跟MySQLServer建立TCP连接,之后按照其定义好的协议进行交互或者比较方便的办法是调用SDK,比如NativeCAP1JDBC、PHP等各语言MySQL Connector,或者通过ODBC。但通过SDK来访问MySQL,本质上还是在TCP连接上通过MySQL协议跟MySQL进行交互。
MySQL Server结构可以分为如下的三层:连接层/服务层/引擎层
不包括物理磁盘上文件/也不包括文件系统
3 第一层:连接层
功能:建立 TCP 连接
经过三次握手建立连接成功后,MySQL服务器对TCP 传输过来的账号密码做身份认证&权限获取。
- 用户名或密码不对,会收到一个Access denied for user错误,客户端程序结束执行
- 用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依赖于此时读到的权限
3.1 数据库连接池(Connection Pool)
一个系统只会和MySQL服务器建立一个连接吗?只能有一个系统和MySQL服务器建立连接吗?
当然不是,多个系统都可以和MySQL服务器建立连接,每个系统建立的连接肯定不止一个。
为了解决TCP无限创建与TCP频繁创建销毁带来的资源耗尽、性能下降问题。MySQL服务器里有专门的TCP连接池 限制连接数。采用 长连接模式 复用TCP连接,来解决上述问题。
TCP 连接收到请求后,必须要分配给一个线程专门与这个客户端的交互。所以还会有个线程池,去走后面的流程,每一个连接从线程池中获取线程,省去了创建和销毁线程的开销。
连接池的最大线程数可以通过参数max-connections
来控制,如果到来的客户端连接超出该值时,新到来的连接都会被拒绝,关于最大连接数的一些命令主要有两条:
show variables like '%max_connections%'
;:查询目前DB的最大连接数。set GLOBAL max_connections = 200;
:修改数据库的最大连接数为指定值。
对于不同的机器配置,可以适当的调整连接池的最大连接数大小,以此可以在一定程度上提升数据库的性能。除了可以查询最大连接数外,MySQL本身还会对客户端的连接数进行统计,对于这点可以通过命令show status like "Threads%";
查询:
所以连接管理的职责是负责认证、管理连接、获取权限信息。
4 第二层:服务层
第二层架构主要完成大多数的核心服务功能,如SQL接口,并完成 缓存的查询 ,SQL的 分析和优化 及部分 内置函数的执行 。所有 跨存储引擎的功能 也在这一层实现,如过程、函数等。
在该层,服务器会 解析查询 并创建相应的内部 解析树 ,并对其完成相应的 优化 :如确定查询表的顺序,是否利用索引等,最后生成相应的执行操作。
如果是SELECT语句,服务器还会 查询内部的缓存 。如果缓存空间足够大,这样在解决大量读操作的环境中能够很好的提升系统的性能。
- SQL Interface:SQL 接口
-
- 接收用户的SQL命令,并且返回用户需要查询的结果。比如SELECT.FROM就是调用SQLInterface。
- MySQL支持DML(数据操作语言)、DDL(数据定义语言)、存储过程、视图、触发器、自定义函数等多种SQL语言接口
- Parser:解析器
-
- 在解析器中对 SQL 语句进行语法分析、语义分析。将SQL语句分解成数据结构,并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的,如果在分解构成中遇到错误,那么就说明这个SQL语句是不合理的。
- 在SQL命令传递到解析器的时候会被解析器验证和解析,并为其创建 语法树 ,并根据数据字典丰富查询语法树,会验证该客户是否具有执行该查询的权限,创建好语法树后,MySQL还会对SQI查询进行语法上的优化,进行查询重写。
- Optimizer: 查询优化器
-
- SQL语句在语法解析之后、查询之前会使用查询优化器确定 SQL语句的执行路径,生成一个 执行计划 。
- 这个执行计划表明应该 使用哪些索引 进行查询(全表检索还是使用索引检索),表之间的连接顺序如何最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询,并将查询结果返回给用户。
- 它使用“选取-投影-连接”策略进行查询。例如:
SELECT id,name FROM student WHERE gender ='女';
这个SELECT查询先根据WHERE语句进行 选取 ,而不是将表全部查询出来以后再进行gender 过滤。
这个SELECT查询先根据id和name进行属性 投影 ,而不是将属性全部取出以后再进行过滤,将这两个查询条件 连接 起来生成最终查询结果。
- Caches& Buffers: 查询缓存组件
-
- MySQL内部维持着一些cache和Bufer,比如Query cache用来缓存一条SELECT语句的执行结果,如果能够在其中找到对应的查询结果,那么就不必再进行査询解析、优化和执行的整个过程了,直接将结果反馈给客户端。
- 这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等。
- 这个查询缓存可以在 不同客户端之间共享 。
- 从MySQL5.7.20开始,不推荐使用查询缓存,并在 MySQL8.0 中删除 (命中率很低)。
5 第三层:存储引擎层
存储引擎也可以理解成MySQL
最重要的一层,在前面的服务层中,聚集了MySQL
所有的核心逻辑操作,而引擎层则负责具体的数据操作以及执行工作。
存储引擎是MySQL
数据库中与磁盘文件打交道的子系统,不同的引擎底层访问文件的机制也存在些许细微差异,引擎也不仅仅只负责数据的管理,也会负责库表管理、索引管理等,MySQL
中所有与磁盘打交道的工作,最终都会交给存储引擎来完成。
MySQL
目前有非常多的存储引擎可选择,其中最为常用的则是InnoDB
与MyISAM
引擎,可以通过show variables like '%storage_engine%';
命令来查看当前所使用的引擎。其他引擎如下:
Oracle、SQLServer
等数据库的实现只有一个存储引擎,因为它们是闭源的,所以仅有官方自己提供的一种引擎。
和其它数据库相比,MySQL有点与众不同,它的架构可以在多种不同场景中应用并发挥良好作用,主要体现在存储引擎的架构上,插件式的存储引擎 架构将查询处理和其它的系统任务以及数据的存储提取相分离。这种架构可以根据业务的无求和实际需要选择合适的存储引擎。 同时开源的 MySQL 还允许 开发人员设置自己的存储引擎。
这种高效的模块化架构为那些希望专门针对特定应用程序需求(例如数据仓库、事务处理或高可用性情况)的人提供了巨大的好处,同时享受使用一组独立于任何接口和服务的优势存储引擎。
插件式存储引擎层(storage Engines),真正的负责了MySQL中数据的存储和提取,对物理服务器级别维护的底层数据执行操作,服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取。
6 存储层 — 文件系统(不属于 MySQL 架构)
这一层则是MySQL数据库的基础,本质上就是基于机器物理磁盘的一个文件系统,其中包含了配置文件、库表结构文件、数据文件、索引文件、日志文件等各类MySQL运行时所需的文件,这一层的功能比较简单,也就是与上层的存储引擎做交互,负责数据的最终存储与持久化工作。
主要可分为两个模块:1. 日志模块 2. 数据模块
所有的数据,数据库、表的定义,表的每一行的内容,索引,都是存在 文件系统 上,以 文件 的方式存在的,并完成与存储引擎的交豆。当然有些存储引擎比如InnoDB,也支持不使用文件系统直接管理裸设备,但现代文件系统的实现使得这样做没有必要了。在文件系统之下,可以使用本地磁盘,可以使用DAS、NAS、SAN等各种存储系统。
6.1 日志模块
在MySQL
中主要存在七种常用的日志类型,如下:
- ①
binlog
二进制日志,主要记录MySQL
数据库的所有写操作(增删改)。 - ②
redo-log
重做/重写日志,MySQL
崩溃时,对于未落盘的操作会记录在这里面,用于重启时重新落盘(InnoDB
专有的)。 - ③
undo-logs
撤销/回滚日志:记录事务开始前[修改数据]的备份,用于回滚事务。 - ④
error-log
:错误日志:记录MySQL
启动、运行、停止时的错误信息。 - ⑤
general-log
常规日志,主要记录MySQL
收到的每一个查询或SQL
命令。 - ⑥
slow-log
:慢查询日志,主要记录执行时间较长的SQL
。 - ⑦
relay-log
:中继日志,主要用于主从复制做数据拷贝。
上述列出了MySQL
中较为常见的七种日志,但实际上还存在很多其他类型的日志,不过一般对调优、排查问题、数据恢复/迁移没太大帮助,用的较少,因此不再列出。
6.2 数据模块(数据的文件存储格式)
MySQL
的所有数据最终都会落盘(写入到磁盘),而不同的数据在磁盘空间中,存储的格式也并不相同,因此再列举出一些MySQL
中常见的数据文件类型:
db.opt
文件:主要记录当前数据库使用的字符集和验证规则等信息。.frm
文件:存储表结构的元数据信息文件,每张表都会有一个这样的文件。.MYD
文件:用于存储表中所有数据的文件(MyISAM
引擎独有的)。.MYI
文件:用于存储表中索引信息的文件(MyISAM
引擎独有的)。.ibd
文件:用于存储表数据和索引信息的文件(InnoDB
引擎独有的)。.ibdata
文件:用于存储共享表空间的数据和索引的文件(InnoDB
引擎独有)。.ibdata1
文件:这个主要是用于存储MySQL
系统(自带)表数据及结构的文件。.ib_logfile0/.ib_logfile1
文件:用于故障数据恢复时的日志文件。.cnf/.ini
:MySQL
的配置文件,Windows
下是.ini
,其他系统大多为.cnf
。
1.7 架构总结
- 连接层: 客户端和服务器端建立连接,客户端发送 SQL至服务器端;
- SQL层(服务层): 对SQL语句进行查询处理;与数据库文件的存储方式无关;
- 存储引擎层: 与数据库文件打交道,负责数据的存储和读取。
巩固知识
- 画出整体架构,分别有什么模块
- 每个模块具体做什么
- SQL 指令执行流程