MySQL程序架构

从架构图可以看出 MySQL 的分层设计非常清晰、解耦充分。

本文按连接层 → 服务层 → 存储引擎层 → 文件系统层逐层讲解,并串联"一条 SQL 的完整生命周期"。


一、架构总览

MySQL 服务器从上到下分为四层:

层次 核心组件 职责
连接层 Connection Pool(连接池/连接处理) 连接建立、认证、线程分配与复用、连接数限制
服务层 SQL Interface、Parser、Optimizer、Caches & Buffers SQL 接收、解析、优化、结果返回、管理服务
存储引擎层 可插拔的存储引擎(InnoDB/MyISAM...) 数据的存储与读取、事务实现
文件系统层 系统文件、数据/索引文件、各类日志 与操作系统交互,真正落盘

外部程序(应用程序、MySQL Shell、各种连接器)发出的请求自上而下穿过这四层。


二、连接层(Connection Pool)

2.1 客户端的连接方式

MySQL 支持四种连接方式:

方式 说明
TCP/IP 最常用,mysql -h 127.0.0.1 -P 3306
Unix Socket 本机连接,mysql -S /var/run/mysqld/mysqld.sock,不走网络,性能好
命名管道(Named Pipe) Windows 专用
共享内存(Shared Memory) Windows 专用

2.2 连接处理流程

⚠️ 重要:MySQL 服务器默认不使用 epoll / Reactor 模型。这一点要和 Redis、muduo 严格区分:

  • Redis/muduo:单(少)线程 + epoll IO 多路复用,一个线程管大量连接;
  • MySQL :默认采用 one-thread-per-connection模型,每个连接由一个独立线程以阻塞式 I/O处理自己的 socket。

真实流程:

  1. MySQL 启动时,主线程创建 listen socket 并监听 3306;
  2. 新连接到达时,主线程 accept 取出连接(监听 socket 底层用 poll/vio 等待,不是 epoll);
  3. 为该连接创建一个专用线程(或从线程缓存 Thread Cache 中取一个空闲线程);
  4. 该线程负责这个连接的整个生命周期:认证 → 循环接收 SQL → 执行 → 返回;
  5. 连接断开后,线程不立即销毁,而是放入 Thread Cache 供下一个连接复用(由 thread_cache_size 控制)。

源码对应:

  • Connection_acceptor / Mysqld_socket_listener:监听与 accept;
  • Per_thread_connection_handler:每连接一个线程;
  • do_handle_one_connection():线程在一个连接上的命令循环。

2.3 连接层各组件(Connection Pool )

组件 作用
Authentication(认证) 握手、校验用户名密码、IP、分配权限
Thread Reuse(线程复用) 断开的线程进入 Thread Cache 复用,避免频繁创建销毁
Connection Limits(连接限制) 受 max_connections 限制,超限返回 too many connections
Check Memory 连接建立时检查内存资源
Caches 连接级缓存(如 prepared statement、线程级缓冲)

2.4 长连接与短连接

  • 长连接 :连接建立后持续使用、不断开(连接池、客户端默认)。缺点是长期累积内存(如连接的临时缓冲、统计信息),可能导致 OOM;可用 mysql_reset_connection 或定期重连释放。
  • 短连接:每次执行完 SQL 就断开,频繁建连开销大(TCP 握手 + 认证 + 线程创建)。。

2.5 线程池(Thread Pool,企业版/插件)

需要注意:图中"连接池"是连接管理,不是线程池。

  • MySQL 企业版 Thread Pool / Percona / MariaDB 提供 :多个工作线程 + 监听线程,Linux 上用 epoll 管理大量连接,类似 Reactor;
  • MySQL 社区版默认不带,仍然是 one-thread-per-connection。

三、服务层(Management Services & Utilities + SQL Core)

连接建立后,客户端发送 SQL,进入服务层。

3.1 NoSQL Interface(NoSQL 接口)

  • MySQL 5.6+ 提供 InnoDB Memcached 插件,允许应用绕过 SQL 层,直接用 memcached 协议对 InnoDB 表做 CRUD,省去解析和优化开销;
  • 8.0 中该插件仍存在,但使用极少,属于历史遗留的 NoSQL 能力。

3.2 SQL Interface(SQL 接口)

  • 客户端 SQL 的统一入口:接收 DML、DDL、存储过程、视图、触发器、存储函数等;
  • 支持的语句经此分发到后续解析、优化、执行模块;
  • 同时返回结果集、受影响行数、状态信息。

3.3 Parser(解析器)

解析器分三步:

  1. 词法分析(Lex):把 SQL 文本切分成一个个 token(关键字、标识符、字面量);
  2. 语法分析(Yacc/Bison) :按语法规则生成解析树,若语法错误(如关键字拼写错、括号不匹配)直接返回错误,不再往下走;
  3. 语义解析/预处理(Resolve) :检查表名、列名是否存在、解析视图、校验权限、确定数据类型。

3.4 Optimizer(优化器)

优化器发现多个执行路径时,基于统计信息和成本模型(Cost Model)选择成本最低的方案。

主要工作:

优化类型 举例
条件化简 WHERE id > 5 AND id > 10 → WHERE id > 10
选择访问路径 全表扫描、索引、范围扫描、ref、const
决定 JOIN 顺序 多表 JOIN 时选择驱动表与被驱动表
子查询改写 部分子查询转 semi-join、派生表合并
索引选择 根据基数、回表成本选择索引
条件下推 ICP 把条件下推到引擎层过滤

可用 EXPLAIN 查看优化器最终选择的执行计划。

3.5 Caches & Buffers

⚠️ 8.0 删除了 Query Cache(查询结果缓存,QC)------因为它在多核、写入频繁场景下锁竞争严重、命中率低。

缓存/缓冲 作用
InnoDB Buffer Pool 缓存表数据页和索引页,最重要的内存区域,读写都优先经过它
Redo Log Buffer redo log 先写内存,再刷盘
Change Buffer 二级索引非唯一页的延迟更新(在 Buffer Pool 中)
Adaptive Hash Index InnoDB 自动为热点索引页建哈希索引
Table Cache(table_open_cache) 缓存已打开表的定义和 handler
Thread Cache 缓存断开连接的线程
Host Cache 缓存客户端主机的连接/错误信息
Prepared Statement Cache 缓存预处理语句

3.6 管理服务与公共组件

它是一组横向贯穿的管理能力:

组件 作用
Backup & Recovery 备份恢复:mysqldump、XtraBackup、基于 binlog 的 PITR
Security 安全:用户认证、权限系统、角色、TDE 透明加密、审计、SSL
Replication 主从复制:异步/半同步、GTID、binlog 复制
Cluster 集群:MGR(Group Replication)、InnoDB Cluster/ClusterSet
Partitioning 表分区:range/list/hash/key 分区
Instance Manager / Administrator 实例管理:mysqladmin、SHOW STATUS/VARIABLES、监控
Migration Toolkit 迁移工具:MySQL Workbench、数据库迁移向导

这些功能不属于单条 SQL 的执行路径,而是为整个数据库实例提供管理、高可用和扩展能力。


四、存储引擎层(Pluggable Storage Engines)

4.1 可插拔设计:handler 接口

服务层与存储引擎之间通过统一的 handler 接口解耦:

  • 每打开一张表,就创建一个对应引擎的 handler 对象(如 InnoDB 的 ha_innobase);
  • 服务层只调用抽象方法:rnd_next()、index_first()、write_row()、update_row()、delete_row()、external_lock() 等;
  • 至于底层数据怎么存、怎么找、锁怎么加、事务怎么实现,完全由引擎决定。

因此 MySQL 可以在同一个服务层下插拔不同引擎,甚至不同表用不同引擎。

4.2 各引擎简述

引擎 特点
InnoDB(默认) 支持 ACID 事务、行级锁、MVCC、外键、崩溃恢复(redo/undo)
MyISAM 5.5 之前默认,表锁、不支持事务、崩溃易损坏,读多写少
MEMORY 数据全在内存,默认哈希索引,重启丢失,适合临时表
CSV 数据存为 CSV 文本文件,可直接用 Excel 查看
ARCHIVE 高压缩比,只支持插入/查询,适合归档历史数据
BLACKHOLE 写入数据被丢弃,binlog 仍记录,常用于级联复制中转
MERGE 把多个同结构 MyISAM 表逻辑合并
FEDERATED 访问远程 MySQL 表,本地不存数据
EXAMPLE / CUSTOM 示例引擎 / 自定义引擎

4.3 存储引擎做什么

收到执行计划后,引擎按 SQL 执行具体的 CRUD:

  • 查询:先查 Buffer Pool,命中直接返回;未命中则向操作系统发起读文件请求,把数据页加载进 Buffer Pool;
  • 写入:修改 Buffer Pool 中的页(脏页),写 redo/undo,后续异步刷盘;
  • 加锁、实现事务隔离、维护索引。

五、文件系统层(File System Layer)

5.1 系统文件(basedir)

类型 内容
服务器程序 mysqld 主程序(/usr/sbin/mysqld)
工具包 mysql、mysqldump、mysqladmin、mysqlcheck 等客户端
配置文件 /etc/mysql/my.cnf、mysql.conf.d、conf.d

5.2 数据与索引文件(datadir,默认 /var/lib/mysql)

文件 作用
mysql/ 等系统库 用户、权限、时区、日志表等
ibdata1 InnoDB 系统表空间(旧版本数据/undo 也在其中)
db/table.ibd 独立表空间(file-per-table,数据+索引)
undo_001/002 undo log,回滚与 MVCC
#innodb_redo/ 8.0.30+ redo log 文件
#innodb_doublewrite/ doublewrite 双写缓冲,防页损坏

5.3 各类日志文件

日志 内容
Binary Log 所有数据变更,用于复制和 PITR
Redo Log 物理日志,崩溃恢复(引擎层)
Undo Log 逻辑回滚段,事务回滚、MVCC
Error Log 启动/关闭、错误、警告、提示
General Query Log 所有 SQL 记录
Slow Query Log 慢查询、未用索引语句
DDL Log DDL 操作的崩溃恢复

六、一条 SQL 的完整生命周期(串联全流程)

以 SELECT * FROM t_user WHERE id = 1; 为例:

  1. 连接建立:客户端通过 TCP 连 3306,主线程 accept;
  2. 认证与线程分配:校验用户名密码,分配一个线程(或从 Thread Cache 取);
  3. 接收 SQL:线程阻塞读取 SQL,交给 SQL Interface;
  4. 解析(Parser):词法分析 → 语法分析生成解析树 → 检查表/列/权限;
  5. 优化(Optimizer):基于成本和统计信息,决定走主键索引,生成执行计划;
  6. 执行(Executor):通过 handler 接口调用 InnoDB;
  7. 引擎读取 :先查 Buffer Pool,命中返回;未命中则向 OS 发起系统调用读 .ibd 文件,加载数据页;
  8. 结果返回:沿线程 → 连接 → 客户端返回结果。

如果是 UPDATE/INSERT/DELETE,还会经过:写 undo → 修改 Buffer Pool(脏页)→ 写 redo(WAL)→ 提交,后续由后台线程刷脏页

相关推荐
论文复现现场1 小时前
2026 低成本 AI Agent 模型怎么选?DeepSeek V4.1 Flash、Qwen3.8 Flash、GLM-5.3 Flash 对比
数据库·人工智能·qwen·ai agent·glm·deepseek
你看我名字2 小时前
云计算工程师技能树:从 Linux 基础到云平台架构能力
linux·架构·云计算
摇滚侠9 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试10 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
晶捷软件10 小时前
从 IT 架构视角看 ERP 选型:用友、金蝶与鼎捷生态(含晶捷智能)的技术差异
架构·智能制造·erp·制造业信息化
@大迁世界10 小时前
Firefox 本地模式:localhost 再见了 ?
前端·架构
深蓝AI10 小时前
总榜第一不等于最划算:Intelligence Index v5 换代后,模型选型要算的三笔账
程序员·架构
天远数科10 小时前
零信任架构实战:基于天远企业股权变更构建自动化商业银行对公授信存续期股权异动与资产抽逃预警网关
运维·人工智能·架构·自动化
2501_9377671611 小时前
自建 SQL 数据库定时备份踩坑复盘与落地思路
数据库·sql