一条 SQL 语句执行全过程
MySQL 基础架构示意图:
上面统称为 Server 层,下面为 存储引擎层
Server层:连接器、缓存、分析器、优化器,执行器。所有跨存储引擎功能的实现,比如:存储过程、触发器,视图
PS: 存储过程,触发器,视图在实际生产开发过程中很少使用
- 连接器:与客户端建立连接,获取权限,维护和管理连接,连接建立后权限不会变化
- xx缓存:对于查询语句,首先查缓存,缓存的 key 为 SQL 语句本身。缓存命中率极低,新版 8.0 已废弃
- 分析器:词法分析、语法分析,校验 SQL 语句是否正常
- 优化器:优化 SQL 语句执行效率,确认执行方案。比如使用哪个索引,多表 join 时确定执行顺序
- 执行器:校验连接权限,调用存储引擎接口查询数据
存储引擎层:为上层提供接口,实现数据的存储和提取。 存储引擎为表级别的配置,默认 InnoDB
SQL 执行过程
SQL 查询语句实际就是将上述所有模块走了一遍
对于修改语句来说,也会将上述所有模块走一遍。区别在于:对于缓存模块,修改语句会删除对应表的所有缓存
修改语句相比查询额外涉及服务层的 binlog 日志及存储引擎层的 redo log 日志
redo log
InnoDB 存储引擎独有的日志,主要用来提高效率,容灾:
WAL: Write-ahead-logging,先写日志(缓冲),再更新磁盘,避免每次修改都需要直接更新磁盘
具体来说,每次修改先记录到 redo log,并更新内存,在后续空闲或者 redo log 写满的时候,更新到磁盘。优势:
- 提效,不用每次修改都查找更新磁盘
- 容灾(crash-safe),即使数据库发生异常重启,之前提交的记录也不会丢失
redo log 本身也记录在磁盘,不过因为顺序写的原因,效率高
binlog
Server 层日志,所有存储引擎共享。binlog 日志主要用来归档,它和 redo log 日志区别如下:
- redo log 是 InnoDB 特有日志,binlog 是 Server 层共享日志
- redo log 是物理日志,记录具体的数据的修改。binlog 是逻辑日志,记录原始 SQL 语句
- redo log 具备 crash-safe 容灾能力,大小固定(一般为 4G),循环写。binlog 追加写,不覆盖
两阶段提交
修改语句的执行链路:
- 执行器调用引擎查询数据(先查内存,没有就查磁盘)
- 执行器根据 SQL 语句修改记录,调用引擎修改接口写入数据
- 引擎将记录更新到内存,并写入 redo log,此时 redo log 处于 prepare 状态,返回执行器
- 执行器将这通操作写入 binlog,调用存储引擎提交事务接口
- 引擎将 redo log 状态修改为 commit,更新完成
其中 redo log 经历两种状态:prepare 和 commit,需要提交两次。两阶段提交的原因:保证 redolog 和 binlog 的状态一致,保证 crash-safe,防止主从同步、扩容等操作后主库,主库从库数据不一致
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。