当前位置: 首页 > news >正文

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 一致性。

http://www.dtcms.com/a/351823.html

相关文章:

  • FreeRTOS学习笔记(四):任务执行与切换
  • ProfiNet 转 Ethernet/IP基于西门子 S7 - 1500 与罗克韦尔 PLC 的汽车零部件加工线协同案例
  • 基于微服务的水果分销系统-项目分享
  • LeetCode 3000.对角线最长的矩形的面积:一次遍历
  • 【golang长途旅行第32站】反射
  • 【机器学习深度学习】连续微调与权重合并的陷阱与最佳实践
  • 修改C盘缓存文件路径
  • MongoDB /redis/mysql 界面化的数据查看页面App
  • UCIE Specification详解(八)
  • 在MiniOB源码中学习使用Flex与Bison解析SQL语句-第一节
  • Rust 环境搭建与 SeekStorm 项目编译部署(支持中文)
  • Robrain V2.0正式登场:落地人形机器人,引爆智能进化革命
  • Ubuntu操作系统下使用mysql、mongodb、redis
  • [特殊字符] CentOS 7 升级 OpenSSH 10.0p2 完整教程(含 Telnet 备份)
  • 如果 我退休了
  • 汽车域控中Hypervisor方案极致安全原理与弊端
  • APP UI自动化测试的思路总结
  • 破解豆瓣Ajax动态加载:Python爬取完整长评论和短评
  • Java面试实战系列【JVM篇】- JVM内存结构与运行时数据区详解(私有区域)
  • 数据结构:链式队列尝试;0826
  • poi生成word固定表格列宽
  • Spring - 文件上传与下载:真正的企业开发高频需求——Spring Boot文件上传与下载全场景实践指南
  • 位运算卡常技巧详解
  • Charles抓包微信小程序请求响应数据
  • 信号无忧,转决千里:耐达讯自动化PROFIBUS集线器与编码器连接术
  • 快速了解卷积神经网络
  • springweb项目中多线程使用详解
  • 问:单证硕士含金量是否不足?
  • 【Linux 进程】进程程序替换
  • 【GitHub】使用SSH与GitHub交互