MySQL 执行过程

MySQL 的执行流程也确实是一个复杂的过程,它涉及多个组件的协同工作,故而在面试或者工作的过程中很容易陷入迷惑和误区。

MySQL 执行过程

本篇将以 MySQL 常见的 InnoDB 存储引擎为例,为大家详细介绍 SQL 语句的执行流程。从连接器开始,一直到事务的提交和数据持久化。

首先,客户端会与 MySQL Server 连接,并发送增删改查语句,Server 收到语句后会创建一个解析树,进行优化。

优化器优化语句时,会评估各种索引的代价,选择合适的索引,然后通过执行器调用 InnoDB 引擎的接口来执行语句。

具体执行流程

1. 连接器(Connection Manager)

MySQL 的执行流程始于连接器。当客户端请求与 MySQL 建立连接时,连接器负责处理这些连接请求。

它验证客户端的身份和权限,然后分配一个线程来处理该连接。MySQL 每个连接线程会创建一个会话(session),在这个会话中,客户端可以发送 SQL 语句进行增删改查等操作。

2. 分析器(Parser)

一旦连接建立,客户端可以发送待执行的 SQL 语句。

这些 SQL 语句首先被送到分析器,分析器的任务是解析 SQL 语句,确定其语法是否正确,并将其转化为一个内部数据结构,以供 MySQL 后续使用。

如果 SQL 语句有语法错误,分析器将返回错误信息给客户端。

3. 优化器(Optimizer)

一旦 SQL 语句被成功解析,接下来进入优化器的领域。

优化器的任务是评估该 SQL 语句不同的执行计划,并选择最优的执行计划。它会考虑哪些索引可用,哪种连接方法效率最高,以及如何最小化查询的成本。

4. 执行器(Executor)

执行器接收到优化器生成的执行计划后,它开始执行实际的查询操作。

执行器会按照执行计划中的步骤,调用 InnoDB 引擎层的逻辑并从数据表中获取数据,然后进行排序、聚合、过滤等操作。

最终,执行器将结果返回给客户端。

5. 写 undo log

当执行器执行修改数据的操作时,MySQL 的 InnoDB 引擎首先会开启事务,为这些修改生成 undo log(也叫回滚日志)。

回滚日志用于记录修改前的数据,以便在事务回滚时恢复原始数据。如果事务执行失败,MySQL 可以使用undo log 来撤销已经进行的修改。

6. 记录缓存(Record Cache),查找索引

MySQL 使用记录缓存来存储从数据表中读取的数据行,这个缓存可以加速对频繁读取的数据的访问,避免了每次都要从磁盘读取的开销。

当数据存在于内存中时,只需要更新内存即可;反之则可能需要从磁盘中读取数据,再更新磁盘数据。

这取决于 MySQL 的索引类型,可分为两种:

  • 唯一索引:索引列的值唯一,非主键的唯一索引允许有空值,主键索引不允许空值;
  • 普通索引:没有特殊限制,允许重复值和空值;

当 SQL 操作数据到达这一步时,InnoDB 首先会判断数据页是否在内存中:

  • 在内存中,判断更新的索引是否是唯一索引。如果是唯一索引,则判断更新后是否破坏数据的一致性,不会的话就直接更新内存中的数据页;如果是非唯一索引,直接更新内存中的数据页。
  • 不在内存中:判断更新的索引是否是唯一索引。如果是唯一索引,由于需要保证更新后的唯一性,所以需要立即把数据页从磁盘加载到内存,然后更新数据页;如果是非唯一索引,则将数据更新的操作记录到 change buffer,它将在在空闲时异步更新到磁盘。

7. change buffer

change buffer 是 InnoDB 引擎的特性之一,在 MySQL 5.5 之前,change buffer 的主要作用是提高数据插入的性能,又被称作 insert buffer。

我们知道,当非聚集索引插入时,数据会按主键的顺序存放,所以叶子节点可能需要离散地访问数据索引页,每次索引页更新时,都需要刷新磁盘。而每次读写磁盘的时间都会很久,故而导致插入性能较低。

而 insert buffer 开启后,会先判断聚集索引页是否存在于缓冲池中,如果有,直接插入;如果不在,先放入一个插入缓冲区进行排序,再以一定的频率合并(merge)更新索引页。

如图所示,insert buffer 将多次操作合并起来,以减少随机 I/O,减少和磁盘交互的操作,从而提升整体的性能。

MySQL5.5 之后,逐渐加入了数据删除和修改的缓冲类型,统一叫 change buffer。

一言概之,change buffer 主要作用是将二级索引的增删改(IDU)操作缓存下来,以减少随机 I/O,达到操作合并的效果。

由于唯一索引需要立即 IO 到磁盘,以保证数据不冲突,因此唯一索引没有 change buffer 机制。

8. 写 redo log

在 SQL 执行的过程中,InnoDB 还会记录所有的数据修改操作到 redo log(重做日志)中。

重做日志是一个循环写入的日志文件,它记录了事务的每个步骤,以确保数据的持久性。如果系统崩溃, InnoDB 可以根据 redo log 来恢复未提交的事务,以保持数据的一致性。

注意,redo log 分为 prepare 和 commit 两个状态。在事务执行的过程中,InnoDB 把数据页的更改写入到 redo log 时,其状态为 prepare 状态。

9. 写 binlog,提交事务

除了 redo log,MySQL 还会记录 binlog(二进制日志)。

二进制日志记录了所有执行的 SQL 语句,而不仅仅是数据修改,这对于数据复制和恢复非常重要,因为它可以确保不仅数据的状态被恢复,连同执行的 SQL 操作也能被还原。

当 InnoDB 引擎层写好 redo log 后,会通知 MySQL Server 层已将更新操作已经执行完成。这时,MySQL Server 将执行的 SQL 写入到 binlog,然后通知 InnoDB 将 redo log 置为 commit 状态,事务提交成功。

注意,一个事务提交成功的判断依据在于是否写入到 binlog 日志中。若已写入,即便 MySQL Server 崩溃,之后也可以根据 redo log 和 binlog 进行恢复。

redo log 和 binlog

上面说到了,当事务提交时,分为两个阶段,我们总结一下:

  1. 数据更新时,先更新内存中的数据页,将更新操作写入到 redo log 中,此时 redo log 进入 prepare 状态。并通知 MySQL Server 更新执行完了,随时可以提交;
  2. MySQL Server 根据持久化的模式是 STATEMENT 还是 ROW,决定将更新的 SQL 还是数据行写入到 binlog,然后调用 InnoDB 的接口将 redo log 设置为 commit 状态,更新完成。

细心的同学可能会问了,为什么 binlog 只需要提交一次,而 redo 要提交两次?而已经有 redo log了,还需要 binlog 干啥?

要解答这个问题,得从两种日志的本质区别说起。

redo log

用于记录 InnoDB 引擎下事务的日志,支持崩溃数据自修复。

如果只写 binlog,而不写 redo log,当 MySQL 发生故障宕机时,就可能会丢失最近执行的事务数据。

binlog

binlog 记录了 MySQL Server 层对数据库执行的所有更改操作,用于数据归档、数据备份及主从复制等。

如果写了 redo log 直接提交,不经过 prepare 阶段,那么这个过程在发生故障时,如果 MySQL 部署了主从节点,主节点可以根据 redo log 恢复数据,但从节点就无法同步这部分数据。

从上图可以看出,MySQL 主从复制时,主要依赖 Master 节点的 binlog,Slave 节点的 relay-log 和 3 个重要线程。

log dump线程

当从节点连接主节点时,主节点会为其创建一个 log dump 线程,用于读取和发送 binlog 内容。在读取 binlog 中时,log dump 线程会对主节点上的 bin-log 加锁,直到读取完成,锁释放。

主节点会为自己的每一个从节点创建一个 log dump 线程。

I/O线程

当从节点绑定主节点时,会创建一个 I/O 线程用来连接主节点,请求主库中的 binlog。

当主库的 log dump 线程发送的日志被监听到以后,I/O 线程会把日志保存到 relay-log(中继日志)中。

SQL线程

SQL 线程负责监听并读取 relay-log 中的内容,解析成具体的操作并进行重放,使其和主数据库保持一致。每次执行完毕后相关线程会进行休眠,等待下一次唤醒。

从库会在一定时间间隔内探测主库的 bin-log 日志是否发生变化,如有变化,则开启 IO 线程,继续执行上述步骤。

参考:微信公众平台​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/823169.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch:升级索引以使用 ELSER 最新的模型

在此 notebook 中,我们将看到有关如何使用 Reindex API 将索引升级到 ELSER 模型 .elser_model_2 的示例。 注意:或者,你也可以通过 update_by_query 来更新索引以使用 ELSER。 在本笔记本中,我们将看到使用 Reindex API 的示例。…

如何安装ubuntu kylin(优麒麟)系统

半个月前(2020-12-25),优麒麟官方发布消息说,优麒麟与 CodeWeavers 公司积极合作适配,正式推出 CrossOver 优麒麟版本,使优麒麟系统能够兼容运行 Windows 应用。将微信(crossover版) 和 QQ(crossover版) 上架麒麟软件商店。 优麒…

143.【Nginx-02】

Nginx-02 (五)、Nginx负载均衡1.负载均衡概述2.负载均衡的原理及处理流程(1).负载均衡的作用 3.负载均衡常用的处理方式(1).用户手动选择(2).DNS轮询方式(3).四/七层负载均衡(4).Nginx七层负载均衡指令 ⭐(5).Nginx七层负载均衡的实现流程 ⭐ 4.负载均衡状态(1).down (停用)(2)…

Linux:apache优化(2)—— 网页传输压缩

网页传输压缩 客户端在请求httpd服务器数据,httpd服务器在返回数据包给客户端时,先对返回的数据进行压缩,压缩之后再传输 作用:配置 Apache 的网页压缩功能,是使用 Gzip 压缩算法来对 Apache 服务器发布的网页内容进行…

【办公软件】Excel双坐标轴图表

在工作中整理测试数据,往往需要一个图表展示两个差异较大的指标。比如共有三个数据,其中两个是要进行对比的温度值,另一个指标是两个温度的差值,这个差值可能很小。 举个实际的例子:数据如下所示,NTC检测温…

JavaEE - 网络编程之回显服务器

目录 一.什么是回显服务器? 二.UDP是什么? 1.TCP 是有链接的, UDP 是无连接的 2.TCP是可靠传输的,UDP是不可靠传输的 3.TCP是面向字节流的,UDP是面向数据报 4.TCP和UDP是全双工的 三.UDP的 socket api 四. 具体代码实现 …

【三维目标检测/自动驾驶】IA-BEV:基于结构先验和自增强学习的实例感知三维目标检测(AAAI 2024)

系列文章目录 论文:Instance-aware Multi-Camera 3D Object Detection with Structural Priors Mining and Self-Boosting Learning 地址:https://arxiv.org/pdf/2312.08004.pdf 来源:复旦大学 英特尔Shanghai Key Lab /美团 文章目录 系列文…

Vue Echarts 多折线图只有一条X轴(合并X轴数据并去重排序) - 附完整示例

echarts:一个基于 JavaScript 的开源可视化图表库。 目录 效果 一、介绍 1、官方文档:Apache ECharts 2、官方示例 二、准备工作 1、安装依赖包 2、示例版本 三、使用步骤 1、在单页面引入 echarts 2、指定容器并设置容器宽高 3、数据处理&am…

nginx+keepalived实现七层负载

目录 一、部署nginx01、nginx02 二、keepalived配置(抢占模式、master- backup模式) 三、测试 四、非抢占模式(backup-backup模式) nginx01 11.0.1.31nginx0211.0.1.32虚拟IP(VIP)11.0.1.30 一、部署ngin…

Qt 5.9.4 转 Qt 6.6.1 遇到的问题总结(一)

最近公司对大家的开发的硬件环境进行了升级,电脑主机的配置、显示器(两台大屏显示器)变得的逼格高多了。既然电脑上的开发环境都需要重装,就打算把开发环境也升级到最新版本,要用就用最新版本。下面对升级后的开发环境…

两向量叉乘值为对应平行四边形面积--公式推导

两向量叉乘值为对应平行四边形面积--公式推导 介绍 介绍

C# 通过SharpCompress.Archives.Rar解压RaR文件

/// <summary>/// 解压一个Rar文件/// </summary>/// <param name"RarFile">需要解压的Rar文件&#xff08;绝对路径&#xff09;</param>/// <param name"TargetDirectory">解压到的目录</param>/// <param name&…

排序算法-插入排序

文章目录 排序算法-直接插入排序算法说明从小到小排序C#代码运行结果 从大到小排序C#代码运行结果 排序算法-直接插入排序 算法说明 直接插入排序是一种简单的排序算法&#xff0c; 它的基本思想是将一个记录插入到已经排序好的有序表中&#xff0c; 从而得到一个新的、记录数…

Spring6入门

1、入门 1.1、环境要求 JDK&#xff1a;Java17&#xff08;Spring6要求JDK最低版本是Java17&#xff09;Maven&#xff1a;3.6Spring&#xff1a;6.1.2 1.2、构建模块 &#xff08;1&#xff09;构建父模块spring6 在idea中&#xff0c;依次单击 File -> New -> Proj…

PHP序列化总结2--常见的魔术方法

魔术方法的概念 PHP的魔术方法是一种特殊的方法&#xff0c;用于覆盖PHP的默认操作。它们以双下划线&#xff08;__&#xff09;开头&#xff0c;后面跟着一些特定的字符串&#xff0c;如__construct()、__destruct()、__get()等。这些魔术方法在对象执行特定操作时被自动调用…

【nodejs】前后端身份认证

前后端身份认证 一、web开发模式 服务器渲染&#xff0c;前后端分离。 不同开发模式下的身份认证&#xff1a; 服务端渲染推荐使用Session认证机制前后端分离推荐使用JWT认证机制 二、session认证机制 1.HTTP协议的无状态性 了解HTTP协议的无状态性是进一步学习Session认…

【开源】基于Vue+SpringBoot的就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

ssm基于Web的老年公寓信息管理系统论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#x…

Java Swing GUI实现ATM机(涉及网络编程聊天功能)

一、序言 1.首先这是本人大二时期的编程&#xff0c;涉及到网络编程的聊天功能&#xff0c;大佬勿喷。 二、且看展示图片 1.首先启动服务端&#xff08;启动Fuwuduan代码&#xff09;&#xff0c;也就是客服聊天窗口 提供给用户申请银行卡号&#xff0c;客服界面如下&#x…

oracle-sga-shared_pool

shared pool 缓冲sql语句和执行计划 shared pool由三部分组成 free libray&#xff1a;缓存sql执行计划 row cathe &#xff1a;缓存数据字典 硬解析&#xff1a;1判断语法2判断对象是否存在3有没有权限4 从n个执行方案中选出最优解&#xff0c;生成执行计划&#xff0c;这一…