MySQL设计架构
·
MySQL
常见版本
MySQL Community Server
社区版本,开源免费
,但不提供官方技术支持
MySQL Enterprise Edition
企业版本,需付费
,可以试用30天
MySQL Cluster
集群版,开源免费
。可将几个MySQL Server
封装成一个Server
MySQL Cluster CGE
高级集群版,需付费
数据库排名网站
http://db-engines.com/en/ranking
MySQL设计架构
- 共分为
4
层:网络连接层
、数据库服务层
、存储引擎层
、系统文件层
网络连接层
- 综述:
MySQL
是一个单进程多线程
架构的数据库
,通过数据库连接池
处理所有客户端接入
的工作 如何连接
:- 当输入命令
mysql -h 127.0.0.1 -uroot -p123456
后MySQL服务端
与客户端
会基于TCP/IP协议栈
建立tcp连接
,这之间会检查用户名、密码、权限
等 - 数据库连接
建立成功
后,MySQL服务端
与客户端
之间会采用半双工的通讯机制
工作 - 同时
MySQL
会安排一条线程
维护当前客户端的连接
,这条线程
也会时刻关注着
当前连接在干什么工作
,可以通过show processlist
命令查询所有正在运行的线程
- 当输入命令
#查看正在运行的线程
mysql> show processlist;
+----+-----------------+-----------------+------+---------+-------+------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-----------------+-----------------+------+---------+-------+------------------------+------------------+
| 5 | event_scheduler | localhost | NULL | Daemon | 66608 | Waiting on empty queue | NULL |
| 8 | root | localhost:65030 | NULL | Query | 0 | init | show processlist |
+----+-----------------+-----------------+------+---------+-------+------------------------+------------------+
2 rows in set, 1 warning (0.00 sec)
event_scheduler
:事件调度器账户
数据库连接池
- 产生原因:所有的
客户端
连接都需要一条线程
去维护,而线程
资源无论在哪里
都属于宝贵资源
,因此不可能无限量创建
,所以这里的连接池
就相当于Tomcat
中的线程池
,主要是为了复用线程
、管理线程
以及限制最大连接数的
连接池
的最大线程数
可以通过参数max-connections
来控制,如果到来的客户端
连接超出该值时
,新到来的连接
都会被拒绝
,关于最大连接数
的一些命令
主要有两条
:show variables like '%max_connections%';
查询目前数据库
的最大连接数
set GLOBAL max_connections = 200;
修改数据库
的最大连接数
为指定值
- 对于
不同的机器配置
,可以适当的调整连接池
的最大连接数大小
,以此可以在一定程度上
提升数据库的性能
。除了可以查询最大连接数
外,MySQL本身
还会对客户端
的连接数进行统计
,对于这点可以通过命令show status like "Threads%";
查询
- 产生原因:所有的
#查看线程的状态
mysql> show status like "Threads%";
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 0 |
| Threads_connected | 1 |
| Threads_created | 1 |
| Threads_running | 2 |
+-------------------+-------+
4 rows in set (0.00 sec)
其中各个字段的释义如下:
Threads_cached
:目前空闲
的数据库连接数
Threads_connected
:当前数据库存活
的数据库连接数
Threads_created
:MySQL-Server
运行至今,累计创建的连接数
Threads_running
:目前正在执行的数据库连接数
数据库服务层
MySQL
大多数核心功能
都位于这一层
,包括客户端SQL请求解析
、语义分析
、查询优化
、缓存
以及所有的内置函数
(例如:日期、时间、统计、加密函数...
),所有跨引擎
的功能
都在这一层
实现,譬如存储过程、触发器和视图
等一系列服务
。
SQL接口组件
作用
:接收客户端
的SQL命令
,比如DML、DDL语句
以及存储过程、触发器
等,当收到SQL语句
时,SQL接口
会将其分发
给其他组件
,然后等待
接收执行结果
的返回
,最后会将其返回
给客户端
- 简单来说,也就是
SQL接口
会作为客户端连接
传递SQL语句
时的入口
,并且作为数据库
返回数据
时的出口
SQL语句
分为五大类
:DML
:数据库操作语句
,比如update、delete、insert
等都属于这个分类
DDL
:数据库定义语句
,比如create、alter、drop
等都属于这个分类
DQL
:数据库查询语句
,比如最常见的select
就属于这个分类
DCL
:数据库控制语句
,比如grant、revoke
控制权限的语句都属于这个分类
TCL
:事务控制语句
,例如commit、rollback、setpoint
等语句属于这个分类
解析器
- 主要作用是
词法分析
、语义分析
、语法树生成
等等,即验证SQL语句
是否正确
,以及将SQL语句
解析成MySQL
能看懂
的机器码指令
优化器
- 作用是
生成执行计划
,比如选择最合适
的索引
,选择最合适
的join方式
等,最终会选择出一套最优
的执行计划
,维护当前连接的线程
会负责
根据计划
去执行SQL
缓存和缓冲区
读取缓存
- 一般指
select语句
的数据缓存
,当然也会包含一些权限缓存
、引擎缓存
等信息,但主要还是select语句
的数据缓存
作用
:MySQL
会对于一些经常执行
查询的SQL语句
,将其结果
保存在Cache缓存
中,因为这些SQL语句
经常执行
,因此如果下次
再出现相同的SQL
时,能从内存缓存
中直接命中数据
,自然会比走磁盘
效率更高注意
:高版本
的MySQL
中,移除
了查询缓存区
,毕竟命中率
不高,而且查询缓存
这一步还要带来额外开销
,同时一般程序
都会使用Redis
做一次缓存
,因此结合多方面
的原因
就移除了查询缓存的设计
- 一般指
写入缓冲区
缓冲区
的设计
主要是:为了通过内存
的速度
来弥补磁盘速度
较慢对数据库造成的性能影响
数据库
进行写操作
时,都会先从缓冲区
中查询是否有要操作的页
,如果有
,则直接对内存
中的数据页
进行操作
(例如修改、删除等
),对缓冲区
中的数据操作
完成后,会直接
给客户端
返回成功的信息
,然后MySQL
会在后台
利用一种名为Checkpoint
的机制
,将内存
中更新的数据
写到磁盘
MySQL
在设计
时,通过缓冲区
能减少大量的磁盘IO
,从而进一步
提高数据库整体性能
存储引擎层
存储引擎
也可以理解成MySQL
最重要的一层
,在前面的服务层
中,聚集了MySQL
所有的核心逻辑操作
,而引擎层
则负责具体的数据操作
以及执行工作
Oracle、SQLServer
等商用数据库
只有一个存储引擎
,因为它们是闭源
的,所以仅有官方自己提供
的一种引擎
。而MySQL
则因为其开源特性
,所以存在很多很多款
不同的存储引擎
实现,MySQL
为了能够正常搭载不同
的存储引擎
运行,因此引擎层
是被设计
成可拔插式的
,也就是可以根据业务特性
,为自己的数据库
选择不同的存储引擎
MySQL
目前有非常多的存储引擎
可选择,其中最为常用
的则是InnoDB
与MyISAM
引擎,可以通过show variables like '%storage_engine%'
; 命令来查看当前所使用的引擎
。
#查看存储引擎
mysql> show variables like "%storage_engine%";
+---------------------------------+-----------+
| Variable_name | Value |
+---------------------------------+-----------+
| default_storage_engine | InnoDB |
| default_tmp_storage_engine | InnoDB |
| disabled_storage_engines | |
| internal_tmp_mem_storage_engine | TempTable |
+---------------------------------+-----------+
4 rows in set, 1 warning (0.01 sec)
存储引擎
是MySQL
数据库中与磁盘文件
打交道的子系统
,不同的引擎
底层访问文件的机制
也存在些许细微差异
,引擎
也不仅仅只负责数据的管理
,也会负责库表管理、索引管理
等,MySQL
中所有与磁盘
打交道的工作,最终都会交给存储引擎
来完成
文件系统层
- 这一层主要分为
两个板块
:①日志板块
。②数据板块
。该层是MySQL数据库
的基础
,本质上
就是基于机器物理磁盘
的一个文件系统
,其中包含了配置文件、库表结构文件、数据文件、索引文件、日志文件
等各类MySQL
运行时所需的文件
,这一层
的功能比较简单
,也就是与上层
的存储引擎
做交互
,负责数据
的最终存储
与持久化工作
日志板块
:使用七种
常用的日志类型
binlog二进制
日志,主要记录MySQL数据库
的所有写操作
(增删改
)redo-log重做/重写
日志,MySQL崩溃
时,对于未落盘的操作
会记录在这里面
,用于重启时
重新落盘
(InnoDB专有的
)undo-logs撤销/回滚
日志:记录事务开始前
(修改数据
)的备份
,用于回滚事务
error-log错误
日志:记录MySQL启动、运行、停止时的
错误信息`general-log常规
日志,主要记录MySQL
收到的每一个查询或SQL命令
slow-log慢查询
日志,主要记录执行时间较长
的SQL语句
relay-log
:中继日志
,主要用于主从复制
做数据拷贝
数据板块
:MySQL
的所有数据
最终都会落盘
(写入到磁盘
),而不同的数据
在磁盘空间
中,存储的格式
也并不相同
,常见的数据文件类型
如下db.opt
文件:主要记录当前数据库
使用的字符集
和验证规则
等信息.frm
文件:存储表结构
的元数据信息文件
,每张表
都会有一个这样的文件
.MYD
文件:用于存储表中所有数据
的文件
(MyISAM引擎
独有的).MYI
文件:用于存储表中索引信息
的文件
(MyISAM引擎
独有的).ibd
文件:用于存储表数据和索引信息
的文件
(InnoDB引擎
独有的).ibdata
文件:用于存储共享表空间的数据
和索引
的文件
(InnoDB引擎
独有).ibdata1
文件:这个主要是用于存储MySQL系统
(自带
)表数据
及结构
的文件
.ib_logfile0/.ib_logfile1
文件:用于故障数据恢复
时的日志文件
.cnf/.ini
:MySQL
的配置文件
,Windows
下是.ini
,其他系统大多为.cnf
架构小结
查看最大连接数
mysql> show variables like "%max_connections%";
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| max_connections | 151 |
| mysqlx_max_connections | 100 |
+------------------------+-------+
2 rows in set, 1 warning (0.00 sec)
查询缓存配置情况
mysql> show variables like "%query_cache%";
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | NO |
+------------------+-------+
1 row in set, 1 warning (0.00 sec)
一条SQL语句执行流程
连接层
(1)提供连接协议:TCP/IP 、SOCKET
(2)提供验证:用户、密码,IP,SOCKET
(3)提供专用连接线程:接收用户SQL,返回结果
通过以下语句可以查看到连接线程基本情况
mysql> show processlist;
SQL层
(1)接收上层传送的SQL语句
(2)语法验证模块:验证语句语法,是否满足SQL_MODE
(3)语义检查:判断SQL语句的类型
DDL :数据定义语言
DCL :数据控制语言
DML :数据操作语言
DQL: 数据查询语言
...
(4)权限检查:用户对库表有没有权限
(5)解析器:对语句执行前,进行预处理,生成解析树(执行计划),说白了就是生成多种执行方案.
(6)优化器:根据解析器得出的多种执行计划,进行判断,选择最优的执行计划
代价模型:资源(CPU IO MEM)的耗损评估性能好坏
(7)执行器:根据最优执行计划,执行SQL语句,产生执行结果
执行结果:在磁盘的xxxx位置上
(8)提供查询缓存(默认是没开启的),会使用redis tair替代查询缓存功能
(9)提供日志记录(日志管理章节):binlog,默认是没开启的。
存储引擎层(类似于Linux中的文件系统)
负责根据SQL层执行的结果,从磁盘上拿数据。
将16进制的磁盘数据,交由SQL结构化化成表,
连接层的专用线程返回给用户。
一条 SQL 语句在 MySQL 中的执行流程通常包括以下步骤:
1. **客户端发送 SQL 查询**:
客户端通过网络连接发送 SQL 查询到 MySQL 服务器。
2. **连接建立**:
MySQL 服务器接收到客户端发送的 SQL 查询,并建立与客户端的连接。
3. **解析器解析 SQL 查询**:
MySQL 服务器中的解析器解析客户端发送的 SQL 查询,分析语法和语义,并将其转换为内部的执行计划。
4. **优化器优化执行计划**:
优化器对解析后的 SQL 查询进行优化,选择最佳的执行计划以提高执行效率。
5. **存储引擎执行查询**:
MySQL 服务器根据优化后的执行计划,调用相应的存储引擎执行查询操作。
6. **锁管理器处理并发访问**:
如果查询涉及到数据的读写操作,锁管理器负责处理并发访问,确保事务的隔离性和一致性。
7. **数据读取或修改**:
存储引擎根据执行计划从磁盘或缓存中读取数据,或者进行数据的修改操作。
8. **日志管理器记录事务日志**:
如果查询涉及到事务的修改操作,日志管理器负责记录事务日志,以实现事务的持久性和恢复能力。
9. **返回结果给客户端**:
存储引擎将查询结果返回给 MySQL 服务器,MySQL 服务器再将结果返回给客户端。
10. **连接关闭**:
客户端完成对查询结果的处理后,关闭与 MySQL 服务器的连接。
这是一条 SQL 查询在 MySQL 中的基本执行流程。在执行过程中,MySQL 会根据查询的具体情况进行优化和调整,以提高执行效率和性能。
更多推荐
所有评论(0)