很多人都用过MySQL,可能有些人对MySQL的结构和底层比较模糊。这里简单介绍下。
MySQL架构
首先看下一个随处可见的架构图,也是大家对MySQL可插拔式存储引擎吹捧的原因
从图中可以看出大致分八个组件,这里简单说明下:
组件 | 功能 | 说明 |
---|---|---|
Connectors | 连接客户端 | |
Management Service & Utilities | 系统管理控制工具、备份、灾难恢复、分区管理、集群等 | |
Connection Pool | 连接池:权限管理、安全、连接管理、缓存等 | |
SQL Interface | 接受来自客户的命令,DML、DDL、存储过程、视图、触发器等 | |
Parser | 解析器:对SQL语句进行语法分析、词法分析,生成语法树 | |
Optimizer | 优化器:在执行前对SQL进行优化,并生成执行计划 | |
Cache & Buffer | 查询缓存:默认关闭,8.0版本已经移除 | |
Pluggalbe Storage Engines | 插件式存储引擎:管理内存、索引,与文件系统打交道 | |
File System | 文件系统:数据、索引、普通日志、Redo、Undo、错误日志等 |
一个简单的查询大概经过:
1.要想实现一个查询,客户端首先需要能连接到服务器。
2.然后客户端把一个SQL查询发送到服务器,被Parser进行语法分析、词法分析,之后生成语法树
3.生成的语法树,交给Optimizer进行优化
4.交给存储引擎层进行处理。而该层对File System进行管理
Connectors
说白了就是我们连接数据的客户端,如JDBC等。
我们知道,MySQL的与服务器的连接是长连接、半双工的。熟悉网络的可能对这个比较熟悉。而且这个连接最大允许传输数据是4M。
查询缓存
先说它是因为在MySQL 5.7中,它默认是关闭的。而且在8.0版本中已经废弃。它本质上在caches模块中维护一个 K-V 键值对。
Parser
经过语法解析、词法解析得到语法树。
Optimizer
优化器,目的就是找到执行SQL最优的执行计划。我们知道一个MySQL表可能有多种索引和检索方式。但是具体用哪种方式,需要优化器优化后进行选择。
物理优化
-
等价变化规则(去除无用的条件、优化等价规则)
-
基于联合索引调整查询条件位置
逻辑优化
-
根据存储引擎优化count、min、max等
-
针对覆盖索引扫描优化
-
针对冗余子查询优化
-
执行SQL提前终止查询(提前判断找不到)
-
where子句中 in 的优化
具体的可以查看执行计划,有两种方式:
一、desc、explain
二、打开SQL的执行计划追踪开关。打开方式:
set global optimizer_trace='enabled-on';
打开后,每一句SQL的执行计划都放入 optimizer_trace 表中,供DBA查阅。
具体的参数和含义,这里就不多说了。
结构化查询
SQL(Structure Query Language)。这里简单列举下常见的一些描述:
含义 | 举例 | |
---|---|---|
DQL | 数据查询语言 Data Query Language | SELECT、FROM、WHERE |
DML | 数据操纵语言 Data Manipulation Language | INSERT、UPDATE、DELETE |
DPL | 事务处理语言 | BEGIN TRANSACTION、COMMIT和ROLLBACK |
DCL | 数据控制语言 | GRANT、REVOKE,对数据库对象的访问权限 |
DDL | 数据定义语言 | CREATE、DROP创建、删除表,以及为表加索引 |
CCL | 指针控制语言 | DECLARE CURSOR、FETCH INTO和UPDATE WHERE CURRENT |
其实都是SQL92的一部分,可能很多人喜欢纠结定义而已。
存储引擎
MySQL最值得称道的就是其可插拔存储引擎层。而且是基于表的。比如早先版本是MyISAM,现在版本默认都是InnoDB。当然根据应用场景需要也可以自由选择。这里简单列举下,当然还要其他的比如NDB等也有一定的使用场景。
存储引擎 | 特点 | 应用场景 | 说明 |
---|---|---|---|
CSV | 没有索引,列必须Not Null,列不能自增 CSV文件存储,即逗号分隔的表格文件 | 数据导入导出 | |
Archive | ARZ文件格式的压缩存储,磁盘占用率小 只能insert和select 因此只能自增ID列建立索引,也只能一个索引 | 记录日志 数据备份、采集、归档 | |
Memory | 存储在内存中,表大小上限默认16M 不支持大数据字段,如Blog、text、varchar Hash索引,即等值查询 可靠性比较低,服务器重启会丢失 | 数据快速加载 临时表存储 | |
MyISAM | 较好的数据插入和读取性能 相比InnoDB磁盘占用小 表级别锁、不支持事务 数据文件与索引文件分开(MYD、MYI) count(*)性能很高 | 适合读多写少 | 5.5以前的默认存储引擎 |
InnoDB | 支持事务ACID 行级别锁 聚集索引、B+树索引 表数据缓存、索引缓存(buffer pool) MVCC | 普适 | 5.5以后默认存储引擎 |
线程
我们知道MySQL是一个单进程、多线程的实例。
后台线程有四种,主要工作如下:
Thread | 作用 |
---|---|
Master Thread | 核心后台线程,负责将缓冲池中的数据异步刷到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲(insert buffer)、UNDO页的回收 |
IO Thread | 负责AIO请求的回调处理 |
Purge Thread | 事务提交后undolog不再需要,负责回收已经使用并分配的undo页 |
Page Cleaner Thread | 脏页的刷新 |