mysql 执行sql流程概述

sql执行流程

解析器(Parser)

作用 :把 SQL 文本转换成数据库能理解的结构化形式。
具体做的事情

  1. 词法分析(Lexical Analysis)
    • 把 SQL 文本拆成 token(关键字、表名、字段名、符号等)。
  2. 语法分析(Syntax Analysis)
    • 根据 SQL 语法规则生成 解析树(Parse Tree)
    • 检查 SQL 是否符合语法规范。
    • 例如:
      SELECT id, name FROM users WHERE age > 18;
      会生成一棵树,表示 SELECTFROM usersWHERE age > 18
  3. 初步语法检查
    • 检查关键字顺序、括号匹配、函数调用是否合法。

预处理器(Preprocessor / Preparser)

作用 :在语义层面检查 SQL,保证执行时可以找到所有对象和权限。
具体做的事情

  1. 权限检查
    • 判断用户是否有权限访问表或列。
  2. 对象存在性检查
    • 检查表、列、视图、函数等是否存在。
  3. 标识符解析
    • 将 SQL 中的表名、列名、别名解析成内部对象指针。
  4. 语义检查
    • 检查列类型匹配、函数参数合法性、聚合函数是否合理等。
  5. 生成准备执行的解析树
    • 解析树被增强,带上表、列的对象信息,为优化器使用。

⚠️ 注意:预处理器不处理执行策略,只检查语义和权限。

MVCC 的处理流程(读操作)

InnoDB 通过 多版本并发控制(MVCC) 来实现非阻塞读(一致性读,Consistent Read)。
关键点

  • 每行数据在内部存储两个隐藏列:
    1. DB_TRX_ID:最近修改这行的事务 ID
    2. DB_ROLL_PTR:指向 Undo Log 的指针(保存修改前的版本)

读操作流程

  1. 事务 T1 执行 SELECT 查询(非锁定读):
    • InnoDB 会检查行的 DB_TRX_ID
    • 对每行:
      • 如果 DB_TRX_ID < T1 的事务开始时间 → 可见。
      • 如果 DB_TRX_ID > T1 的事务开始时间 → 不可见,读 Undo Log 中旧版本。
  2. 从 Undo Log 获取快照
    • Undo Log 记录了行被修改前的旧值。
    • T1 会根据事务开始时间回溯到合适的旧版本。
  3. 保证一致性读
    • SELECT 看到的是 事务开始时刻的数据快照,不会被其他事务未提交的修改影响。

更新事务对索引的处理

当事务 T2 执行 UPDATE/INSERT/DELETE:

  1. 索引和数据页修改顺序
    • InnoDB 先更新索引(叶子节点),再修改数据页。
    • 这是为了保证聚簇索引一致性和快速定位行。
  2. 事务未提交时的可见性
    • 未提交事务修改的数据对其他事务是 不可见的(默认隔离级别是 Repeatable Read / Read Committed)。
    • InnoDB 会在索引页记录事务 ID
      • 其他事务扫描索引时,如果遇到行被未提交事务修改,会判断不可见,从而跳过该行。
      • 所以 索引修改不会影响其他事务读取逻辑,只会在锁冲突时被阻塞(比如 SELECT ... FOR UPDATE)。
  3. 锁和阻塞情况
    • 如果其他事务做的是 共享读(一致性读) → 不受影响。
    • 如果其他事务做的是 修改或 FOR UPDATE → 会等待未提交事务提交或回滚。

sql执行流程图

复制代码
客户端 SQL
    ↓
MySQL Server 接收
    ↓
解析器 (Parser)         → 词法 & 语法分析 → 解析树
    ↓
预处理器 (Preprocessor)  → 权限检查 & 对象解析 → 语义合法的解析树
    ↓
优化器 (Optimizer)       → 逻辑优化 & 访问路径选择 → 执行计划
    ↓
执行引擎 (Execution Engine)   → 真正访问数据页,生成结果
    ↓
  ┌──────────────┐
  │ 读操作: MVCC  │
  │ 写操作:       │
  │   - Buffer Pool 数据页修改
  │   - 生成 Undo Log
  │   - 生成 Redo Log
  └──────────────┘
    ↓
事务提交 (COMMIT)
    ↓
  - Redo Log 刷盘
  - 标记事务已提交
  - Undo Log 保留/异步清理
    ↓
数据页异步落盘(后台线程)
    ↓
返回客户端结果

数据更新流程

复制代码
[应用层 INSERT/UPDATE]
           |
           v
   [Buffer Pool 页修改]
   /                       \
[聚簇索引页]           [二级索引 -> Insert Buffer]
           |
           v
       [Undo Log in Buffer Pool]  <-- 内存记录旧值
           |
           v
      [Redo Log in Log Buffer]  <-- 持久化保证
           |
   [事务提交? flush redo log?]
           |
           v
       [磁盘刷新]
       /       \
[聚簇索引页刷盘] [二级索引页刷盘 via Insert Buffer + Doublewrite]
           ^
           |
     Undo Log 异步写入 undo tablespace

崩溃恢复点标注在:

  • Redo Log:保证事务提交数据可重做

  • Undo Log:回滚未提交事务

  • Doublewrite:保证页完整性

  • Insert Buffer:二级索引也能恢复

  • Undo Log 不需要像 Redo Log 那样同步 flush,每次事务提交主要依赖 Redo Log 保证持久性。

  • Undo Log 的刷盘是异步的,主要为了释放内存和 MVCC 一致性。

相关推荐
许泽宇的技术分享1 小时前
当自然语言遇上数据库:Text2Sql.Net的MCP革命如何重新定义开发者与数据的交互方式
数据库·.net·text2sql·mcp
2301_803554521 小时前
redis学习
数据库·redis·学习
weixin_456588152 小时前
【java面试day19】mysql-优化
java·mysql·面试
Java水解2 小时前
SQL 多表查询:数据整合与分析的强大工具
sql
TT哇2 小时前
@[TOC](MySQL)MySQL经典练习题(详解)
数据库·mysql
Yichen_liuuil2 小时前
Oracle数据库迁移
数据库·oracle·备份·迁移
小李飞刀李寻欢2 小时前
MongoDB /redis/mysql 界面化的数据查看页面App
redis·mysql·mongodb
森之鸟4 小时前
审核问题——鸿蒙审核返回安装失败,可以尝试云调试
服务器·前端·数据库
有技术的小白4 小时前
[特殊字符] 数据库知识点总结(SQL Server 方向)
数据库·sql