MySQL 中一条 SQL 语句的执行流程

在 MySQL 中,一条 SQL 语句的执行并非 "即时完成",而是经过连接器、查询缓存、分析器、优化器、执行器等多个模块的协同处理,最终与存储引擎交互获取数据。

MySQL 架构概述

MySQL 内部分为服务层引擎层。服务层负责 SQL 的解析、优化和执行协调,引擎层负责数据的实际存储与读取,采用插件式结构,支持多种引擎类型(如 InnoDB、MyISAM 等),其中 InnoDB 是 MySQL 的默认存储引擎,具备事务支持、行级锁和外键约束,适用于高并发、数据一致性要求高的场景。

服务层核心组件

连接器

负责客户端与 MySQL 的连接管理,包括身份验证、权限校验和连接维护。验证成功后,MySQL 会为每个客户端连接分配独立线程。

查询缓存

缓存 SQL 查询的结果,命中时直接返回以减少重复计算。但由于数据库数据变化频繁,缓存命中率低,逻辑上浪费性能,MySQL 5.7 版本默认不开启,8.0 版本完全弃用。

分析器

校验 SQL 语法正确性,拆解 SQL 结构,将 SQL 字符串解析为抽象语法树(AST),同时检查涉及的表、字段是否存在及用户是否有权限访问。

优化器

为 SQL 选择成本最低的执行计划,决定索引使用、表连接顺序等执行策略,生成物理执行计划。

执行器

根据优化器生成的执行计划,调用存储引擎接口执行数据操作。

查询语句的执行流程

连接建立与权限验证(连接器)

客户端通过连接器与 MySQL 建立连接,完成身份验证和权限校验,获取连接线程。

SQL 解析与校验(分析器)

分析器对 SQL 进行语法校验,拆解语句结构,生成抽象语法树,检查涉及的表、字段是否存在及用户权限。

执行计划优化(优化器)

优化器基于成本模型选择最佳执行计划,如确定使用的索引、表连接顺序等,生成物理执行计划。

执行计划执行(执行器)

执行器调用存储引擎接口,根据执行计划获取数据。

引擎层数据读取(InnoDB)

  • 缓冲池检查:InnoDB 判断数据所在页是否在内存缓冲池中,若不在则从磁盘读入缓冲池。
  • 数据处理:通过索引查找、数据遍历过滤等操作获取满足条件的数据行,涉及多版本并发控制(MVCC)、临时表排序等逻辑。
  • 结果集组织:将符合条件的数据行组织成结果集,传递给服务层执行器。

结果集处理与返回(服务层)

执行器对引擎层返回的结果集进行筛选、组合、排序、分组聚合等处理,格式化后再次校验权限,最终返回给客户端。

增删改语句执行流程

增删改语句在服务层的执行步骤(连接、解析、优化、执行)与查询语句基本一致,但在引擎层(以 InnoDB 为例)存在显著差异,核心涉及事务处理和日志机制

事务开启与日志准备(InnoDB)

  • 开启事务并获取事务 ID。
  • 生成反向语句(用于回滚),写入 undo log,更新数据行的回滚指针和事务 ID。

数据页处理

  • 缓冲池检查:若目标数据页不在缓冲池,通过唯一索引定位的数据会加载到缓冲池;非唯一索引定位的更新操作记录到 change buffer(延迟更新磁盘,空闲时异步刷新)。
  • 内存更新:直接更新缓冲池中的数据,期间判断数据冲突(如锁竞争)。

事务提交(两阶段提交)

  • prepare 阶段:写入 redo log,标记状态为 "prepare"。
  • binlog 写入:Server 层触发 binlog 模块,将操作逻辑写入 binlog cache 并刷盘。
  • commit 阶段:InnoDB 收到 binlog 写入确认后,将 redo log 刷盘并标记状态为 "commit",事务正式提交。

脏页刷新与结果返回

  • 缓冲池中被修改的脏页不会立即写入磁盘,由后台线程在空闲时异步刷新;即使未刷盘,因 redo log 已持久化,数据库崩溃后可通过 redo log 恢复。
  • 执行器整理结果后返回给客户端。

关键机制说明

  • undo log:用于事务回滚,记录数据修改前的状态。
  • redo log:确保事务持久性,记录数据修改后的状态,崩溃后可恢复未刷盘的脏页。
  • change buffer:优化非唯一索引更新性能,延迟磁盘写入,提升并发效率。
  • 两阶段提交:保证 redo log 与 binlog 的数据一致性,避免单点日志故障导致的数据丢失或不一致。
相关推荐
身如柳絮随风扬14 分钟前
MySQL核心知识
数据库·mysql
想七想八不如1140843 分钟前
数据库--样题复习
数据库·sql·oracle
551只玄猫1 小时前
【数据库原理 实验报告1】创建和管理数据库
数据库·sql·学习·mysql·课程设计·实验报告·数据库原理
q5431470871 小时前
MySQL SQL100道基础练习题
数据库·mysql
zhoupenghui1681 小时前
mysql 中如果条件where中有or,则要求or两边的字段都必须有索引,否则不能用到索引, 为什么?
数据库·mysql·索引
eggwyw3 小时前
完美解决phpstudy安装后mysql无法启动
数据库·mysql
java修仙传3 小时前
MySQL 事务隔离级别详解
数据库·mysql·oracle
Irissgwe3 小时前
MySQL存储过程和触发器专题
数据库·mysql·oracle
551只玄猫4 小时前
【数据库原理 实验报告3】索引的创建以及数据更新
数据库·sql·课程设计·实验报告·操作系统原理
Augustine Electra4 小时前
Flutter 三方库 memoize 的鸿蒙化实战 - 引入极简缓存引擎,避免重复计算,大幅提升鸿蒙应用渲染性能,让你的高刷体验更稳更丝滑。
flutter·缓存·harmonyos