一条 SQL 语句执行全过程

MySQL 基础架构示意图:

image.png

上面统称为 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 写满的时候,更新到磁盘。优势:

  1. 提效,不用每次修改都查找更新磁盘
  2. 容灾(crash-safe),即使数据库发生异常重启,之前提交的记录也不会丢失
redo log 本身也记录在磁盘,不过因为顺序写的原因,效率高

binlog

Server 层日志,所有存储引擎共享。binlog 日志主要用来归档,它和 redo log 日志区别如下:

  1. redo log 是 InnoDB 特有日志,binlog 是 Server 层共享日志
  2. redo log 是物理日志,记录具体的数据的修改。binlog 是逻辑日志,记录原始 SQL 语句
  3. redo log 具备 crash-safe 容灾能力,大小固定(一般为 4G),循环写。binlog 追加写,不覆盖

两阶段提交

修改语句的执行链路:

  1. 执行器调用引擎查询数据(先查内存,没有就查磁盘)
  2. 执行器根据 SQL 语句修改记录,调用引擎修改接口写入数据
  3. 引擎将记录更新到内存,并写入 redo log,此时 redo log 处于 prepare 状态,返回执行器
  4. 执行器将这通操作写入 binlog,调用存储引擎提交事务接口
  5. 引擎将 redo log 状态修改为 commit,更新完成

其中 redo log 经历两种状态:prepare 和 commit,需要提交两次。两阶段提交的原因:保证 redolog 和 binlog 的状态一致,保证 crash-safe,防止主从同步、扩容等操作后主库,主库从库数据不一致


Frisk0309
1 声望0 粉丝

长亭外,古道边,芳草碧连天