2026年7月11日 · 5 分钟阅读
MySQL 架构入门:Server 层、存储引擎、日志文件与 InnoDB 内存结构
基于数据库进阶课程笔记,梳理 MySQL 逻辑架构、日志文件、SQL 执行流程、InnoDB 内存结构、表空间、WAL、Checkpoint 和 Doublewrite。
学习 MySQL 进阶,第一步不是背 SQL 优化口诀,而是先搞清楚一条 SQL 进入 MySQL 后会经过哪些模块、数据最终怎么落到磁盘、日志又在其中扮演什么角色。
MySQL 可以粗略分成两层:Server 层和存储引擎层。Server 层负责连接、解析、优化、执行等通用能力;存储引擎层负责数据真正如何存取。
MySQL 逻辑架构
MySQL 的逻辑架构里常见组件包括:
| 组件 | 作用 |
|---|---|
| Connectors | 负责客户端连接 |
| Connection Pool | 管理连接、认证、权限、线程资源 |
| SQL Interface | 接收 SQL 并返回执行结果 |
| Parser | 词法分析、语法分析,验证 SQL 是否合法 |
| Optimizer | 生成执行计划,选择索引和 join 顺序 |
| Cache / Buffer | 查询缓存,MySQL 8 已移除查询缓存 |
| Pluggable Storage Engines | 插件式存储引擎,如 InnoDB、MyISAM |
这套结构解释了一个事实:SQL 优化不只是“加索引”,解析器、优化器、执行器、存储引擎都会影响最终表现。
一条查询 SQL 的执行流程
以查询语句为例,大致流程是:
- 客户端和连接器建立连接。
- MySQL 校验用户身份和权限。
- SQL 进入解析器,生成语法树。
- 优化器根据成本模型选择执行计划。
- 执行器调用存储引擎接口。
- 存储引擎读取数据页或索引页。
- 执行器过滤、组装结果。
- 结果返回客户端。
优化器会根据成本选择索引、决定多表 join 顺序。EXPLAIN 看到的执行计划,就是优化器选择的结果。
MySQL 日志文件
MySQL 运行过程中会生成多类日志。
| 日志 | 作用 |
|---|---|
| error log | 记录启动、运行和停止过程中的错误 |
| binlog | 二进制日志,用于主从复制、数据恢复 |
| general query log | 记录所有客户端请求 |
| slow query log | 记录慢 SQL |
| redo log | InnoDB 事务重做日志,保证崩溃恢复 |
| relay log | 主从复制中从库保存主库 binlog 事件 |
其中 binlog 和 redo log 最常被问到。binlog 是 Server 层日志,redo log 是 InnoDB 存储引擎日志。
binlog 的作用
binlog 记录数据库变更事件,主要用于:
- 主从复制。
- 数据恢复。
- 审计变更。
- 增量备份。
它记录的是逻辑层面的变更,可以理解为“做了什么 SQL 或行变更”。
InnoDB 存储引擎
InnoDB 是 MySQL 5.5 之后的默认存储引擎,支持事务、行级锁、外键、崩溃恢复,是业务系统里最常用的存储引擎。
InnoDB 和 MyISAM 的典型区别:
| 对比项 | InnoDB | MyISAM |
|---|---|---|
| 事务 | 支持 | 不支持 |
| 锁粒度 | 行锁为主 | 表锁 |
| 崩溃恢复 | 支持 redo log | 较弱 |
| 索引结构 | 聚簇索引 | 非聚簇索引 |
| 适用场景 | OLTP 业务系统 | 读多写少的老场景 |
现代业务系统通常优先选择 InnoDB。
InnoDB 内存结构
InnoDB 内存结构常见四块:
| 结构 | 作用 |
|---|---|
| Buffer Pool | 缓存数据页和索引页 |
| Change Buffer | 缓冲非唯一二级索引的变更 |
| Adaptive Hash Index | 自适应哈希索引 |
| Log Buffer | 缓冲 redo log 写入 |
Buffer Pool 是最核心的内存区域。数据库读写并不是每次都直接访问磁盘,而是尽量在 Buffer Pool 中操作数据页。
Buffer Pool 和脏页
当 InnoDB 修改数据时,通常先修改 Buffer Pool 中的数据页。被修改但还没刷到磁盘的数据页,叫脏页。
如果每次更新都直接随机写磁盘,性能会很差。InnoDB 通过 Buffer Pool、redo log 和刷脏页机制,把大量随机写转化为内存修改和顺序日志写。
这就是数据库写入性能的重要基础。
WAL:日志先行
WAL 全称 Write Ahead Log,意思是日志先行。
InnoDB 修改数据时,会先写 redo log,再在合适时机把脏页刷回磁盘。只要 redo log 安全落盘,即使数据库宕机,也能在重启时根据 redo log 恢复数据。
WAL 的好处:
- 顺序写日志比随机写数据页更快。
- 可以延迟刷脏页。
- 支持崩溃恢复。
redo log 为什么高效
redo log 记录的不是完整数据页,而是页上的物理修改信息。它采用顺序写,比随机写数据页更高效。
redo log 通常循环使用。写满后,如果某些日志对应的脏页还没有刷盘,就不能覆盖这部分日志,这时可能触发 Checkpoint。
Checkpoint
Checkpoint 用来推进脏页落盘进度,并标记哪些 redo log 已经不再需要用于崩溃恢复。
Checkpoint 主要解决:
- 避免数据变更每次都直接写磁盘。
- 缩短数据库崩溃恢复时间。
- Buffer Pool 不够时刷新脏页。
- redo log 空间不足时推进日志可覆盖位置。
Checkpoint 越落后,崩溃恢复需要重放的日志越多。
Doublewrite
脏页刷盘时可能遇到页写入不完整的问题,也就是 partial page write。InnoDB 用 Doublewrite 机制降低风险。
简化流程:
- 脏页先复制到内存中的 Doublewrite Buffer。
- 顺序写入系统表空间中的 Doublewrite 区域。
- 再离散写入各自表空间文件。
- 如果宕机导致页损坏,可以用 Doublewrite 中的副本恢复。
Doublewrite 牺牲一部分写入成本,换取数据页安全。
小结
MySQL 架构可以按这条线理解:
- Server 层负责连接、解析、优化、执行。
- 存储引擎层负责真正的数据读写。
- binlog 服务于复制和恢复。
- InnoDB 通过 Buffer Pool 减少磁盘访问。
- redo log + WAL 保证崩溃恢复和写入性能。
- Checkpoint 和 Doublewrite 解决脏页落盘与页安全问题。
理解这些后,再看事务、索引、锁和性能优化,就不只是背结论,而是在理解 MySQL 为什么这样设计。