MySQL梳理一:整体架构概览

1. MySQL整体架构概览

MySQL 整体来说采用的是客户端-服务器(C/S)架构。对其进行详细分层的话,可以划分为客户端层服务层存储引擎层三大核心部分,每一层负责不同的功能,共同完成从接收用户请求到数据存储和查询的全过程:

  • 客户端层:负责与用户或应用程序交互,接收 SQL 请求并返回结果
  • 服务层 :核心处理层,负责解析、优化、执行 SQL 语句,并管理连接、权限、缓存等 -存储引擎层:负责实际的数据存储和读取,支持多种存储引擎(如 InnoDB、MyISAM 等)

此外,还有一些跨层的功能模块,如连接管理、日志系统和事务管理等

bash 复制代码
客户端(应用程序/JDBC/ODBC/golang的数据库通用接口包database/sql包) 
    ↓↑(通过网络或本地连接)
连接层(连接管理、权限验证)
    ↓↑
服务层(解析器、优化器、执行器、查询缓存)
    ↓↑
存储引擎层(InnoDB、MyISAM、Memory等)
    ↓↑
物理存储(数据文件、日志文件)

1.1 客户端层

作用:客户端层是用户或应用程序与 MySQL 交互的入口,支持多种编程语言和工具(如Navicat、Sequel Pro)

功能

  • 发起 SQL 查询或管理命令(如 SELECTINSERTCREATE TABLE
  • 通过网络协议(如 TCP/IP(可通过SSL/TLS进行加密)、Unix 套接字、Windows中的命名管道及共享内存、SSL/TLS)与 MySQL 服务器建立连接
  • 接收服务器返回的结果集或错误信息

特点

  • 客户端可以是命令行工具、GUI 工具或应用程序代码
  • 客户端与服务器之间的通信通常基于 MySQL 的专用协议(私有的二进制应用层协议MySQL Protocol ,基于 TCP/IP 传输)

1.2 服务层

服务层是 MySQL 的核心,包含了大部分逻辑处理功能

1.2.1 连接管理

作用:管理客户端与服务器之间的连接

功能

  • 接收客户端连接请求,建立通信通道
  • 分配线程池(Thread Pool)或专用线程处理每个连接
  • 进行用户身份认证(基于用户名、密码、主机地址等)
  • 权限验证,确保用户有权执行请求的操作

1.2.2 解析器

作用:解析客户端发送的 SQL 语句,生成解析树

功能

  • 词法分析:将 SQL 语句拆分为词法单元(Token),如关键字、表名、列名等

  • 语法分析:检查 SQL 语句的语法是否正确,确保符合 MySQL 的语法规则

  • 语义分析:验证表、列、函数等是否存在,检查权限和上下文合法性

  • 输出:生成一棵解析树,供后续优化器使用

    sql 复制代码
    SELECT id, name FROM users WHERE age > 18;

    在这个示例中,解析器会识别 SELECTFROMWHERE 等关键字,并验证 users 表和 age 列是否存在

1.2.3 优化器

作用:根据解析树生成高效的执行计划

功能

  • 分析 SQL 语句,评估多种可能的执行路径
  • 根据统计信息(如表的大小、索引分布)选择代价最低的执行计划
  • 优化操作包括选择最优的索引 、决定表连接顺序(对于多表查询) 、改写子查询或简化表达式
  • 支持基于规则的优化(RBO)和基于成本的优化(CBO)
sql 复制代码
SELECT * FROM users JOIN orders ON users.id = orders.user_id WHERE users.age > 18;

对于上述示例sql,优化器可能决定先过滤 users.age > 18,再进行表连接。而如果 users.id 有索引,优化器可能选择基于索引的连接,我们可以使用 EXPLAIN 命令查看优化器的选择

1.2.4 执行器

作用:根据优化器生成的执行计划,调用存储引擎的接口执行查询

功能

  • 按执行计划的步骤,逐一调用存储引擎的 API(如读取行、扫描索引)
  • 对于复杂查询,可能涉及临时表、排序或分组操作
  • 将最终结果集返回给客户端
  • 支持流式返回结果(减少内存占用)或缓存结果(用于排序等)。

需要注意的是, 执行器与存储引擎交互,但不直接操作底层数据文件

1.2.5 查询缓存(MySQL 8.0 前)

缓存 SELECT 查询的文本及其结果,以加速相同查询的响应

由于缓存对表数据的任何修改(如 INSERT、UPDATE)敏感,修改后缓存即失效(从5.7.20就已经开始不推荐查询缓存了),同时也存在性能问题和维护成本,MySQL 8.0 正式移除查询缓存(也是在oracle公司接管以后)。现在通常使用外部缓存如 Redis

1.2.6 其他服务层功能

事务管理:协调事务的开始、提交和回滚,依赖存储引擎实现 ACID 属性

日志管理

  • 二进制日志:记录所有修改操作,用于复制和恢复
  • 慢查询日志:记录执行时间超阈值的查询,用于性能分析
  • 通用日志:记录所有 SQL 操作,调试用
  • 内置函数和存储过程:支持数学、字符串、日期等函数,以及用户定义的存储过程和触发器

1.3 存储引擎层

存储引擎层是 MySQL 的特色,负责实际的数据存储、索引管理和物理操作,采用插件式架构,向上面的服务层提供统一的接口(即存储引擎API),服务层对查询进行优化之后,只需要按照生成的执行计划,调用不同的存储引擎API即可。MySQL允许用户根据需求选择不同的存储引擎

存储引擎决定了数据的存储格式、索引结构、事务支持等。MySQL默认存储引擎为InnoDB,其特性主要包括:

  • 支持事务(ACID 特性)
  • 行级锁,适合高并发场景
  • 支持外键和崩溃恢复
  • 使用聚簇索引,数据按主键组织

其他的存储引擎特性如下:

MyISAM(MySQL从05年推出InnoDB存储引擎前的存储引擎):

  • 不支持事务,表级锁
  • 适合读多写少的场景(如数据仓库)
  • 存储格式紧凑,占用空间小

Memory(不用磁盘来存储数据):

  • 数据存储在内存中,速度快但断电丢失。
  • 适合临时表或缓存。

1.3.1 存储引擎功能

  • 数据存储 :将数据写入磁盘文件(如 InnoDB 的 .ibd 文件)
  • 索引管理:维护 B+ 树、哈希索引等结构
  • 锁机制:实现不同粒度的锁(如 InnoDB 的行锁,MyISAM 的表锁)
  • 事务支持:InnoDB 提供事务日志(Redo Log、Undo Log)实现事务一致性
  • 物理优化:如 InnoDB 的缓冲池(Buffer Pool)缓存热点数据

1.3.2 与服务层的交互

  • 服务层通过标准接口(如 Handler API)与存储引擎通信
  • 存储引擎不解析 SQL,仅响应服务层的请求(如"读取某行""更新某记录")
  • 不同存储引擎对同一 SQL 的执行效率可能差异很大

1.3.3 以InnoDB为例浅析页机制

  • 以页(Page)为单位的磁盘 I/O
  • 内存与磁盘之间的交互机制

InnoDB 将表中的数据持久化存储在磁盘上 ,即使数据库关机重启,数据仍然可以保留,但数据库的读写操作主要发生在内存中 ,因为磁盘 I/O 的速度比内存慢几个数量级,频繁地直接读写磁盘会严重影响性能。为了解决这个问题,InnoDB 引入了页机制

  • 页是磁盘和内存之间交互的基本单位(默认行格式为Dynamic)
  • InnoDB 中的页大小通常为 16KB
  • 不管你要读取一条记录,还是修改一列,最小的加载单位就是一个页

当你执行查询,InnoDB 的流程大致如下:

  1. 判断所需数据所在页是否已在内存中(Buffer Pool)
  2. ✅ 若已在内存:直接从 Buffer Pool 中读取,无需磁盘操作
  3. ❌ 若不在内存:从磁盘中将对应的 16KB 页 读入 Buffer Pool,再从中取出你需要的那一条或几条记录

所以不是"一条一条从磁盘中读记录",而是"一次读一页(16KB),一页中可能包含多条记录"

当你插入或更新数据时:

  1. InnoDB 先在内存中的 Buffer Pool 中修改对应页
  2. 同时写入 redo log (用于崩溃恢复)和 undo log(用于事务回滚)
  3. 后续通过后台线程将修改后的页 异步刷回磁盘 (即刷新脏页

页机制的优点有:

  • 减少磁盘 I/O 次数:一次性读写 16KB,比频繁读写单条记录更高效
  • 数据局部性原理:一页中的记录往往来自相邻主键或同一索引区间,命中概率高
  • 更好地管理缓存:Buffer Pool 以页为单位组织,提高缓存命中率

Buffer Pool,即页的"内存缓存区":

  • 用于缓存数据页(Data Page)、索引页(Index Page)、插入缓冲页等
  • 加速读写,避免频繁访问磁盘
  • 页被淘汰策略通常是 LRU(最近最少使用)

1.3.4 InnoDB聚簇索引查找

聚簇索引结构决定了数据记录在页内和页间的物理组织方式

每个数据页内部

  • InnoDB 会将所有记录通过 单向链表(实际上是一个页内偏移量的列表)连接起来
  • 这些记录根据主键值大小排序
  • 即使做了插入、删除、更新操作,这个链表始终保持主键有序

📌 特点:

  • 记录间通过 next_record_offset 连接
  • 页头有 PAGE_HEAP_TOP(记录起始指针),页尾有 PAGE_DIRECTION(指向最大记录)
  • 插入新记录时,会修改相邻节点的指针,保持顺序

页与页之间的双向链表结构

  • 除了页内记录链表,每个页之间也有一个 双向链表

    • 当前页的 FIL_PAGE_PREV 指向前一页
    • 当前页的 FIL_PAGE_NEXT 指向后一页

📌 这个链表确保了你可以通过页头尾指针快速遍历整个 B+ 树的叶子层

这两种结合的设计带来的好处有 节省空间 + 维护顺序 + 支持范围查找

css 复制代码
[Page 1] ---> [Page 2] ---> [Page 3]     ← 页之间双向链表

Page 1 内部:
[最小记录] -> [记录1(pk=1)] -> [记录2(pk=5)] -> [最大记录]    ← 记录单链表(按主键有序)

在 InnoDB 的聚簇索引中,无论如何增删改数据,页内记录总是通过一个主键有序的单链表连接起来,而数据页之间则通过双向链表连接,构成叶子节点层的可遍历结构。

而当 InnoDB 中的数据页上有记录被标记为删除 后,这些被删除的记录并不会立刻物理删除 (因为涉及事务回滚等机制),而是被链接成一个特殊的单向链表 ,称为 "空闲记录链表" (也俗称"垃圾链表"),链表的入口由页头的字段 PAGE_FREE 指向(记录偏移量),每条被删除的记录中有 next_record 字段,会指向下一个被删除的记录,这些"空间"将被未来插入的数据优先使用

1.3.5 InnoDB 数据页结构 + 聚簇索引查找路径的核心原理

✅ InnoDB 数据页结构中的定位机制全景总结:

🔹 数据页组成(7 个部分):

InnoDB 每个数据页(通常 16KB)由以下 7 个部分组成:

序号 区域名称 功能简述
1 File Header 页的元信息(如页类型、页号)
2 Page Header 页的状态(记录数量、目录指针等)
3 Infimum + Supremum 虚拟最小、最大记录,用于页内链表的边界
4 User Records 用户插入的数据记录
5 Free Space 空闲可用空间(新记录写入位置)
6 Page Directory 槽区 ,用于快速定位记录的索引(重点!
7 File Trailer 校验信息(防止页损坏)

🔹 记录链表:页内记录链结构(主键有序)

  • 每个数据页内部的记录是通过主键顺序 组成的单链表
  • infimum → 第一条用户记录 → 第二条 → ... → supremum
  • 无论插入/删除/更新,InnoDB 始终保持这个链表的主键有序性

🔹 页目录(Page Directory):快速查找关键

页目录位于数据页的末尾,是一个记录偏移量数组,用于加速查找

  • 类似一个"快速跳转索引"
  • 把页中的记录划分为若干组(槽 slot)
  • 每个槽指向该组记录中"最大"的一条记录(即段尾)
  • 页目录中偏移量是降序排列的
  • 通过二分查找快速定位到所属槽,再在线性遍历

🔍 举个形象的查找过程例子

假设我们要查找主键 pk=27,查找路径是:

  1. 根据 B+ 树的聚簇索引结构,定位到含有 pk=27 的数据页;
  2. 在该页中进入页目录部分,使用二分查找定位到"可能包含 pk=27 的槽";
  3. 顺着该槽指向的最大记录向前遍历主键有序的单链表
  4. 找到目标记录或确认不存在

总结:每个数据页中,InnoDB 使用主键有序单链表 组织记录,同时维护一个 页目录(记录指针数组) ,可以通过 二分查找快速锁定槽,再从槽内顺序扫描,提升页内查找性能

1.4 物理存储层

作用:存储实际的数据文件、索引文件和日志文件

主要文件类型

  • 数据文件 :如 InnoDB 的 .ibd(每表独立表空间)或 .frm(表结构定义)
  • 索引文件:存储引擎维护的索引数据(如 InnoDB 索引与数据集成)
  • 日志文件
    • Redo Log:记录事务的修改操作,用于崩溃恢复
    • Undo Log:记录事务的回滚信息,支持 MVCC(多版本并发控制)
    • Binlog:记录逻辑修改,跨存储引擎,用于复制和恢复

存储位置 :由 MySQL 的 datadir 参数指定


1.5 sql执行过程

以下是一个典型 SELECT 查询的执行流程,展示各层如何协作:

  1. 客户端 :发送 SELECT id, name FROM users WHERE age > 18;
  2. 连接层:验证用户身份,建立连接,分配线程
  3. 解析器:解析 SQL,生成解析树,验证语法和语义
  4. 优化器 :分析查询,生成最优执行计划(如使用 age 索引)
  5. 执行器:调用存储引擎接口,按计划执行查询
  6. 存储引擎:读取索引和数据,返回结果集
  7. 服务层:将结果集格式化,返回给客户端
相关推荐
IT_102423 分钟前
Spring Boot项目开发实战销售管理系统——系统设计!
大数据·spring boot·后端
DCTANT1 小时前
【原创】国产化适配-全量迁移MySQL数据到OpenGauss数据库
java·数据库·spring boot·mysql·opengauss
ai小鬼头1 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
Touper.1 小时前
SpringBoot -- 自动配置原理
java·spring boot·后端
一只叫煤球的猫2 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈
一只鹿鹿鹿2 小时前
信息化项目验收,软件工程评审和检查表单
大数据·人工智能·后端·智慧城市·软件工程
专注VB编程开发20年3 小时前
开机自动后台运行,在Windows服务中托管ASP.NET Core
windows·后端·asp.net
程序员岳焱3 小时前
Java 与 MySQL 性能优化:MySQL全文检索查询优化实践
后端·mysql·性能优化
一只叫煤球的猫3 小时前
手撕@Transactional!别再问事务为什么失效了!Spring-tx源码全面解析!
后端·spring·面试
喜欢敲代码的程序员3 小时前
SpringBoot+Mybatis+MySQL+Vue+ElementUI前后端分离版:项目搭建(一)
spring boot·mysql·elementui·vue·mybatis