MySQL 整体架构与存储引擎对比

前三阶段的学习,我们大多聚焦在"怎么写 SQL"、"怎么建表"、"怎么用 Java 连 MySQL"这些偏应用层的技能上。从本篇开始,我们将进入 MySQL 的内核世界,理解它内部是如何组织和运转的。理解了架构,你才能明白为什么有些查询快、有些慢,为什么 InnoDB 是默认引擎,以及如何根据自己的业务场景做出正确的技术选择。

本文将带你了解:

  • MySQL 的四层逻辑架构
  • 各层的主要职责和组件
  • 几种常见存储引擎的特点与对比(InnoDB、MyISAM、MEMORY 等)
  • 如何选择合适的存储引擎
  • 如何查看表使用的引擎及引擎状态
  • 动手实战:创建不同引擎的表并观察其差异

1. MySQL 的"四层小楼":整体架构一览

MySQL 的设计非常有层次感,我们可以把它看成一座四层楼,从上到下分别是:

  1. 连接层 ------ 接待客户
  2. 服务层 ------ 分析需求并制定执行计划
  3. 存储引擎层 ------ 实际干活的人
  4. 文件系统层 ------ 把结果持久化到磁盘

下面逐层来认识。

1.1 连接层:握手与线程

连接层负责与客户端建立连接、验证身份、分配线程。当你执行 mysql -u root -p 时,就触发了这一层的工作流程:

  • TCP 握手:客户端与 MySQL 服务端建立网络连接。
  • 身份验证:核对用户名、密码、主机权限。
  • 线程分配:MySQL 为每个连接分配一个线程,后续这个连接的所有 SQL 都由该线程处理。
  • 连接池管理:MySQL 内部有一个线程池(不同于应用侧的连接池),负责复用线程以降低频繁创建/销毁的开销。

可以通过 SHOW PROCESSLIST 查看当前所有连接及其状态:

sql 复制代码
SHOW FULL PROCESSLIST;

1.2 服务层:大脑与指挥中心

服务层是 MySQL 的核心,绝大多数功能都在这一层实现。即使你从未感知过它,它也在默默工作。

主要组件

  • 查询缓存(Query Cache):MySQL 8.0 已移除该功能,因为在高并发下它反而会成为瓶颈。早期版本会将 SELECT 语句及其结果以 K-V 形式缓存,表数据变更后缓存失效。
  • 解析器(Parser):对 SQL 语句进行词法分析、语法分析,生成一棵"解析树"。如果 SQL 有语法错误,就是在这里被揪出来的。
  • 预处理器(Preprocessor):检查解析树中的表名、列名是否存在,权限是否满足。
  • 查询优化器(Optimizer) :这是服务层最复杂、最重要的模块。它负责为一条 SQL 生成多种可能的执行路径,估算每种路径的代价,并选出代价最低的作为"执行计划"。我们用的 EXPLAIN 就是查看优化器决策结果的工具。
  • 执行器(Executor):按照执行计划,逐条调用存储引擎提供的接口(Handler API)来读写数据。
  • 管理服务与工具:备份、恢复、安全、迁移等功能的入口。

你可以把服务层想象成一个项目经:它接收客户的需求(SQL),理解需求(解析),制定方案(优化),然后安排具体的工人(存储引擎)去执行。

1.3 存储引擎层:真正的数据操盘手

存储引擎是 MySQL 架构中最具特色的部分。它可插拔------你可以为不同的表选择不同的存储引擎,而服务层通过统一的 API 与它们交互,无需关心底层的数据存储细节。

这种设计的巨大优势

  • 你可以在同一个数据库中,为事务型核心表使用 InnoDB,为只读的日志归档表使用 MyISAM(当然现在极少这么做了),为临时计算使用 MEMORY 引擎。
  • 第三方也可以开发自己的存储引擎(如 TokuDB、MyRocks 等)。

1.4 文件系统层:物理持久化

最底层就是操作系统上的文件。存储引擎将数据最终写入磁盘文件,这些文件可能包括:

  • 表数据文件(.ibd
  • 表结构文件(.frm,8.0 后被 data dictionary 取代)
  • 日志文件(redo logundo logbinlog 等)
  • 配置文件等

这部分我们在第四阶段后续文章会深入探究。

一张图总结(文字版)

复制代码
┌──────────────────────────────────────┐
│         客户端 / JDBC / CLI          │
└──────────────┬───────────────────────┘
               │
┌──────────────▼───────────────────────┐
│  连接层:身份验证、线程分配           │
└──────────────┬───────────────────────┘
               │
┌──────────────▼───────────────────────┐
│  服务层:解析、优化、执行            │
│  (解析器 → 优化器 → 执行器)        │
└──────────────┬───────────────────────┘
               │  Handler API
┌──────────────▼───────────────────────┐
│  存储引擎层:InnoDB / MyISAM / ...   │
└──────────────┬───────────────────────┘
               │
┌──────────────▼───────────────────────┐
│  文件系统层:.ibd, .frm, redo log... │
└──────────────────────────────────────┘

2. 常见存储引擎对比

MySQL 支持多种存储引擎,我们重点介绍最常遇到的几种。

2.1 InnoDB ------ 现在的绝对主力

自 MySQL 5.5 起,InnoDB 成为默认存储引擎。它的核心特点:

  • 支持事务(ACID):通过 Redo Log、Undo Log 和 MVCC 实现,是目前唯一内置支持事务的标准引擎。
  • 行级锁:并发读写时锁粒度更细,高并发场景优势明显。
  • 外键支持:保障引用完整性。
  • 聚簇索引:数据按主键顺序存储,主键查询和范围查询很快。
  • 崩溃恢复:通过 Redo Log 实现,即使断电也能保证已提交数据不丢失。
  • 支持热备份 :配合 mysqldumpXtrabackup 等工具可在线备份。

适用场景 :几乎一切 OLTP(在线事务处理)场景,如电商订单、银行交易、社交互动。除非有特殊理由,否则默认用 InnoDB 就对了

2.2 MyISAM ------ 曾经的王者

在 MySQL 早期(5.5 之前),MyISAM 是默认引擎。它的特点:

  • 不支持事务:没有 COMMIT/ROLLBACK,数据一致性靠应用层保证。
  • 表级锁:任何写操作都会锁住整张表,并发写入性能极差。
  • 不支持外键:引用完整性需应用自行维护。
  • 存储结构简单 :每张表对应三个文件------.frm(定义)、.MYD(数据)、.MYI(索引)。
  • 查询速度较快:在少量并发、读写比极高的场景下(如数据仓库、日志归档),其表扫描性能有时略优于 InnoDB(因为表结构更简单,无事务开销)。
  • 支持全文索引:InnoDB 在 5.6 后才支持,但在早期这是 MyISAM 的一大优势。

当前定位 :MySQL 8.0 已逐步淘汰 MyISAM(系统表全部转为 InnoDB)。新项目不应该再使用 MyISAM,除非你维护的是一个无法升级的遗留系统。

2.3 MEMORY(HEAP) ------ 极速但易失

MEMORY 引擎将数据全部存储在内存中,重启后数据丢失(表结构保留)。

  • 速度极快:所有操作都在内存完成。
  • 默认使用 HASH 索引(也可指定 BTREE),适合等值查询。
  • 不支持事务、外键
  • 表级锁
  • 大小受 max_heap_table_size 参数限制(默认 16MB),不能无限增长。

适用场景:缓存表、临时结果集、会话数据等不需要持久化且对速度极度敏感的场景。但注意,在现代架构中,这类需求通常由 Redis 等专用缓存实现,MEMORY 引擎用途已较少。

2.4 其他引擎速览

引擎 特点 使用场景
CSV 数据以 CSV 文件存储,可用 Excel 直接打开 数据交换、快速导出
ARCHIVE 压缩存储,只支持 INSERT 和 SELECT,不支持 UPDATE/DELETE 日志归档、审计数据
BLACKHOLE 写入即丢弃(像 /dev/null) 中继复制、测试
FEDERATED 访问远程数据库的表,类似透明网关 分布式环境(已逐渐被分布式方案替代)
NDB MySQL Cluster 使用的分布式引擎 高可用、高冗余的电信级应用

3. 如何选择存储引擎?

没有哪个引擎是绝对"最好"的,但有"最适合当前场景"的。以下是一条简明的决策路径:

  1. 是否需要事务? 是 → InnoDB;否 → 继续下一步。
  2. 数据是否需要持久化? 否 → 考虑 MEMORY 或 Redis;是 → InnoDB。
  3. 是否只有 INSERT 和 SELECT,且数据量极大又不修改? 是 → 可考虑 ARCHIVE(但通常仍推荐 InnoDB 并开启页压缩)。
  4. 是否需要外键约束? 是 → 只能用 InnoDB。

一句话总结:在 95% 的场景下,直接使用 InnoDB 即可。 现代 MySQL 的优化方向全部围绕 InnoDB 展开,MyISAM 等引擎已经不再积极维护。


4. 查看与设置存储引擎

4.1 查看支持的引擎

sql 复制代码
SHOW ENGINES;

结果中 Support 列显示 DEFAULT 的就是当前默认引擎(通常为 InnoDB)。

4.2 查看某张表的引擎

sql 复制代码
SHOW TABLE STATUS LIKE 'books'\G

关注 Engine 字段。

或通过 INFORMATION_SCHEMA:

sql 复制代码
SELECT TABLE_NAME, ENGINE FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'library_db';

4.3 设置表的引擎

建表时指定

sql 复制代码
CREATE TABLE test_myisam (
    id INT PRIMARY KEY,
    val VARCHAR(100)
) ENGINE=MyISAM;

修改已有表的引擎

sql 复制代码
ALTER TABLE test_myisam ENGINE=InnoDB;

注意:转换引擎是一个代价较高的 DDL 操作,会重建整张表,大表请用在线变更工具(如 pt-online-schema-change)。


5. 实战:观察不同引擎的差异

我们来做一个小实验,直观感受 InnoDB 与 MyISAM 在事务支持和锁粒度上的差异。

5.1 创建两张测试表

sql 复制代码
CREATE TABLE innodb_test (
    id INT PRIMARY KEY,
    name VARCHAR(20)
) ENGINE=InnoDB;

CREATE TABLE myisam_test (
    id INT PRIMARY KEY,
    name VARCHAR(20)
) ENGINE=MyISAM;

INSERT INTO innodb_test VALUES (1, 'hello');
INSERT INTO myisam_test VALUES (1, 'hello');

5.2 事务支持对比

InnoDB(在两个会话中分别执行):

会话 A:

sql 复制代码
START TRANSACTION;
UPDATE innodb_test SET name = 'world' WHERE id = 1;
-- 不提交

会话 B:

sql 复制代码
SELECT * FROM innodb_test WHERE id = 1;  -- 默认隔离级别 REPEATABLE READ 下,读到的是 'hello'(未提交的修改不可见)

会话 A 回滚:

sql 复制代码
ROLLBACK;

会话 B 再查,数据恢复原样。这就是事务隔离性的体现。

MyISAM

会话 A:

sql 复制代码
-- MyISAM 没有事务,直接 UPDATE
UPDATE myisam_test SET name = 'world' WHERE id = 1;

会话 B 立即就能读到 'world',且一旦执行无法回滚。

5.3 锁粒度对比

MyISAM 在执行 UPDATE 时会对整张表加写锁,此时其他会话的读操作也会阻塞(写锁排斥读锁)。你可以用两个会话测试:

会话 A:

sql 复制代码
UPDATE myisam_test SET name = 'aaa' WHERE id = 1;
-- 故意不立即提交(实际上 MyISAM 也没有事务,这句执行后锁立即释放?不,由于安全更新模式或显式 LOCK TABLES 才会持续锁;默认 MyISAM 写操作完成后会立即释放锁。为了演示,可以使用 LOCK TABLES)
LOCK TABLES myisam_test WRITE;

会话 B:

sql 复制代码
SELECT * FROM myisam_test;  -- 会阻塞,直到会话 A 执行 UNLOCK TABLES;

而对于 InnoDB,只锁住被修改的行,其他行可以正常读写。

清理

sql 复制代码
DROP TABLE innodb_test, myisam_test;

6. 小结

MySQL 的架构设计堪称数据库设计的典范,它的分层可插拔结构使得核心服务与存储实现解耦,为不同应用场景提供了灵活的引擎选择。

  • 四层架构:连接层(握手分配线程)→ 服务层(解析/优化/执行,是大脑)→ 存储引擎层(真正存取数据,可插拔)→ 文件系统层(持久化)。
  • InnoDB 是现今的绝对首选:支持事务、行锁、外键、崩溃恢复,几乎覆盖所有 OLTP 需求。
  • MyISAM 已退出历史舞台,只存在于遗留系统中;MEMORY 用于临时缓存但通常被外部缓存代替。
  • 可以通过 SHOW ENGINESSHOW TABLE STATUS 查看引擎信息,用 ALTER TABLE ... ENGINE=... 转换引擎。

理解了整体架构,我们就有了后续深入 InnoDB 物理存储、内存结构、日志系统的地图。下一篇文章,我们将聚焦于 InnoDB 的物理世界,探索表空间、段、区、页这些概念,看清 InnoDB 在磁盘上究竟是怎么存放数据的。

思考题

  1. 为什么说优化器是服务层的"大脑"?EXPLAIN 对它产出的执行计划有什么作用?
  2. 如果有一张存储日志的表,只有 INSERT 和 SELECT,没有 UPDATE/DELETE,你觉得应该用 InnoDB 还是 MyISAM?现在(MySQL 8.0)呢?
  3. 查看你的 library_db 中每张表当前使用的引擎,把它们都统一为 InnoDB。

参考资料


相关推荐
caimouse1 小时前
Reactos 第 4 章 对象管理 — 4.6 对象的访问控制 / 4.7 句柄的遗传和继承
开发语言·windows·架构
C137的本贾尼1 小时前
【实战】分析一张真实业务表的 InnoDB 存储结构
java·大数据·数据库
超梦dasgg1 小时前
亿级数据 不停服务平滑迁移(生产环境实战方案)
java·数据库
j_xxx404_1 小时前
MySQL数据库基础硬核解析:从 C/S 网络服务到磁盘文件与存储引擎
linux·运维·服务器·开发语言·数据库·mysql·ai
我是大猴子1 小时前
死锁,慢sql排查,mysql死锁
数据库·sql
Minxinbb1 小时前
TDSQL for MySQL部署选型
数据库·dba
C137的本贾尼1 小时前
【实战】实现一个带事务与索引的命令行图书借阅系统
数据库·microsoft·oracle
caimouse2 小时前
Reactos 第 4 章 对象管理 — 4.8 系统调用 NtDuplicateObject / 4.9 系统调用 NtClose
开发语言·windows·架构
贺国亚9 小时前
Multi-Agent与Multi-Task编排架构
架构