SQL 语句在 MySQL 中的运行过程
Publish date: Oct 19, 1119
Last updated: Oct 219, 21029
Last updated: Oct 219, 21029
问
在 前面 已经介绍了 MySQL 的架构,那么下一步我们自然会想:
SQL 语句在 MySQL 的各个组件中是如何运行的呢?
本章将讨论以下两类 SQL 语句的运行细节:
- 查询语句 (R: Read)
- 更新语句 (C: Create, U: Update, D: Delete)
答
前提
首先在 MySQL 中创建一张表:
mysql > create table T(ID int primary key, c int)
查询
此时,已经连接上了 MySQL。SQL 查询语句如下:
mysql > select * from T where ID = 10;
运行过程
- 查询缓存:命中即返回结果,否则进入 2;注意:MySQL 8.0 已经无此功能
- 分析器:解析 SQL 语句,做 词法分析 和 语法分析,判断是否满足语法
- 优化器:生成执行计划,此处决定使用 ID 这个索引
- 执行器:执行语句,调用存储引擎的接口,查询结果
- 若 ID 没有索引,则调用接口取表 T 的每行值,看是否满足条件
- 若 ID 有索引,则调用满足条件的第一行,继续满足条件的第二行…
流程图
更新
还是在已经连接 MySQL 的情况下,执行下面的更新语句:
mysql > update T set c = c + 1 where ID = 2;
运行过程
- 清空查询缓存:只要一个表上有更新,就会清空该表上的所有缓存结果
- 分析器:解析 SQL 语句,得知这是一条 更新 语句,继续
- 优化器:决定使用 ID 这个索引
截止目前为止,更新语句 与 查询语句 执行过程相同,下面是它们的不同之处:
日志系统
有两套日志系统:redo log 和 bin log
重做日志
即 redo log,是 InnoDB 引擎特有的日志系统。它是固定大小的。
作用:保证 数据库发生异常重启,之后提交的记录也不会丢失,即 crash-safe
归档日志
即 bin log,是 MySQL Server 层自己的日志系统,跨引擎。
作用:用于归档。
比较
不同之处 | redo log | bin log |
---|---|---|
范围 | InnoDB 引擎特有的 | 所有引擎都可使用 |
格式 | 物理日志 | 逻辑日志,原始逻辑 |
长度 | 空间固定会写完 | 一直追加 |
执行
- 执行器找到 ID = 2 的记录,从磁盘或内存中获取之
- 执行器获取记录后修改,再调用引擎接口写入这行记录
- 引擎将新记录更新到内存,将操作记录在 redolog 中,redolog 处于准备状态,返回通知
- 执行器接收到通知后,生成该操作的 binlog 并写入磁盘
- 执行器调用引擎的提交事务接口,更新 redolog 的状态为提交状态,结束
两阶段提交
为了保证 binlog 和 redolog 日志的一致性