主题
概念卡片:MySQL 架构与 SQL 执行流程
一句话机制
MySQL 分两层:通用的 Server 层(连接器→分析器→优化器→执行器)负责功能,插件式的存储引擎层(InnoDB 默认)负责存取;一条 SQL 从连接、解析、优化到执行,最终由执行器调用引擎接口把数据搬出来。 理解这个分层,是理解「为什么 redo log 是引擎的、binlog 是 Server 的」等一切问题的前提。
两层架构
┌──────────────── Server 层(通用,所有引擎共用)────────────────┐
│ 连接器 → 查询缓存 → 分析器 → 优化器 → 执行器 │
│ 内置函数/存储过程/触发器/视图(跨引擎功能) │
└───────────────────────────────────────────────────────────────┘
↓ 调用接口
┌──────────────── 存储引擎层(插件式)───────────────────────────┐
│ InnoDB(默认,事务+行锁) / MyISAM(表锁) / Memory(内存表) │
└───────────────────────────────────────────────────────────────┘一条 SELECT 的执行流程
| 组件 | 做什么 | 关键点 |
|---|---|---|
| 连接器 | TCP 握手、认证、查权限、管连接 | 权限连接时确定,改权限不影响已有连接 |
| 查询缓存 | 命中直接返回 | 失效频繁;8.0 已移除 |
| 分析器 | 词法解析 + 语法解析 | 识别 select 是关键字、T 是表名、id 是列名 |
| 优化器 | 选索引、定 join 顺序 | 逻辑结果相同、效率不同 |
| 执行器 | 判断权限、调引擎接口取数据 | rows_examined 记扫描行数 |
执行器流程:调引擎「取第一行」接口 → 判断条件 → 调「取下一行」接口循环 → 结果集返回。有索引时调「取满足条件的第一行/下一行」接口。
长连接 vs 短连接
- 长连接:持续用同一连接(推荐,连接建立成本高)
- 短连接:查几次就断开
⚠️ 全用长连接的坑:连接临时内存断开才释放,长连接累积会内存暴涨 → OOM。解法:① 定期断连重连;②
mysql_reset_connection重置连接(不重连、不重认证)。
连接超时
wait_timeout 默认 8 小时,超时空闲连接被断开,客户端再请求报 Lost connection。
常见误解(避坑)
- ❌ "查询缓存很有用,应该开着"。→ 表一有更新(增删改)该表所有缓存全清空,命中率极低;8.0 已彻底移除。
- ❌ "改权限立刻对所有连接生效"。→ 权限在建立连接时读取,只对新连接生效。
- ❌ "执行器扫多少行就是引擎扫多少行"。→
rows_examined是执行器累计的;引擎内部可能一次调用扫多行,两者不等。 - ❌ "MySQL 只有 InnoDB 一个引擎"。→ 插件式架构,还有 MyISAM/Memory 等;只是 InnoDB 是 5.5 后默认。
关联
- 原始资料:01_基础架构:一条SQL查询语句是如何执行的?
- 总览:MySQL技术栈总览
- 相关卡:概念卡片:MySQL日志与两阶段提交(redo 是引擎层、binlog 是 Server 层,正源于此分层)
- 域地图:A00-百科/数据与存储/数据与存储