MYSQL执行一条update语句,期间发生了什么

server/2024/12/19 3:36:57/
  1. 客户端先通过连接器建立连接,连接器自会判断用户身份;

  2. 因为这是一条 update 语句,所以不需要经过查询缓存,但是表上有更新语句,是会把整个表的查询缓存清空的,所以说查询缓存很鸡肋,在 MySQL 8.0 就被移除这个功能了;

  3. 解析器会通过词法分析识别出关键字 update,表名等等,构建出语法树,接着还会做语法分析,判断输入的语句是否符合 MySQL 语法;

  4. 预处理器会判断表和字段是否存在,同时将*替换成所有的列值;

  5. 优化器确定执行计划,因为 where 条件中的 id 是主键索引,所以决定要使用 id 这个索引;

  6. 执行器负责具体执行,会调用存储引擎的接口,通过主键索引树搜索获取 id = 1 这一行记录:

    •   如果 id=1 这一行所在的数据页本来就在 buffer pool 中,就直接返回给执行器更新;

    •   如果记录不在 buffer pool,将数据页从磁盘读入到 buffer pool,返回记录给执行器。

  7. 执行器得到聚簇索引记录后,会看一下更新前的记录和更新后的记录是否一样:

    • 如果一样的话就不进行后续更新流程;

    • 如果不一样的话就把更新前的记录和更新后的记录都当作参数传给 InnoDB 层,让 InnoDB 真正的执行更新记录的操作;

  8. 开启事务, InnoDB 层更新记录前,首先要记录相应的 undo log,因为这是更新操作,需要把被更新的列的旧值记下来,也就是要生成一条 undo log,undo log 会写入 Buffer Pool 中的 Undo 页面,不过在内存修改该 Undo 页面的时候,也需要将修改的信息保存到 redo log中,以便持久化。

  9. InnoDB 层开始更新记录,会先更新内存(同时标记为脏页),然后将记录写到 redo log 里面,这个时候更新就算完成了。为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘(比如redolog的持久化文件写满,此时mysql会阻塞,将脏页数据刷新到磁盘,然后清空redolog持久化文件)。这就是 WAL 技术,MySQL 的写操作并不是立刻写到磁盘上,而是先写 redo 日志,然后在合适的时间再将修改的行数据写到磁盘上。

  10. 至此,一条记录更新完了。

  11. 在一条更新语句执行完成后,然后开始记录该语句对应的 binlog(service层),此时记录的 binlog 会被保存到 binlog cache,并没有刷新到硬盘上的 binlog 文件,在事务提交时才会统一将该事务运行过程中的所有 binlog 刷新到硬盘。

  12. 事务提交(为了方便说明,这里不说组提交的过程,只说两阶段提交):  

    • prepare 阶段:将 redo log 对应的事务状态设置为 prepare,然后将 redo log 刷新到硬盘;

    • commit 阶段:将 binlog 刷新到磁盘,接着调用引擎的提交事务接口,将 redo log 状态设置为 commit(将事务设置为 commit 状态后,刷入到磁盘 redo log 文件);

    • 通过上面保证了两个日志文件的一致性,数据恢复时读取redolog时如果是prepare状态,会拿着里面的XID去binlog中寻找,如果不存在说明后续的binlog持久化失败,为了保证两者的一致性redolog会回退。

  13. 至此,一条更新语句执行完成。


http://www.ppmy.cn/server/151337.html

相关文章

查询三网话费余额接口,移动话费余额接口、电信话费余额接口、联通话费余额的接口+html前端查询UI界面

PHP是直接请求的接口&#xff0c;HTML代码也是直接请求的接口。如果HTML想上线运行&#xff0c;还是需要做下安全的。 下边是PHP代码 <?php // 定义API接口地址和参数 $apiUrl "https://api.taolale.com/api/Inquiry_Phone_Charges/get"; //API文档地址&…

MySQL--索引(详解)

欢迎大家来到权权的博客~欢迎大家对我的博客进行指导&#xff0c;有什么不对的地方&#xff0c;我会及时改进哦~ 博客主页链接点这里–>&#xff1a;权权的博客主页链接 目录 一、本节目标二、简介2.1索引是什么&#xff1f;2.2为什么要使用索引&#xff1f; 三、索引应该选…

Linux Mail 功能解析

在 Linux 系统中&#xff0c;mail 命令是用于发送、接收和管理电子邮件的一个常见工具。它通常是系统默认安装的一部分&#xff0c;主要用于命令行界面&#xff08;CLI&#xff09;下的邮件操作。以下是关于 Linux 中 mail 命令及其相关功能的详细解析。 1. 基本功能&#xff…

鸿蒙Next数据懒加载LazyForEach用法总结

在鸿蒙Next开发中&#xff0c;LazyForEach提供了高效的数据懒加载机制&#xff0c;适用于处理大量数据的列表展示等场景&#xff0c;可有效提升性能和内存管理。以下是其详细用法总结。 一、使用限制 容器组件要求&#xff1a;必须在特定容器组件&#xff08;List、Grid、Swi…

【PHP小课堂】在PHP中使用Zookeeper

在PHP中使用Zookeeper 不知道大家对于 Zookeeper 的了解有多少&#xff0c;我在实际的项目中没有使用过&#xff0c;但是之前学过一点。因此&#xff0c;今天我们只来看看 PHP 中关于 Zookeeper 的扩展相关函数的使用&#xff0c;不会涉及更加深入的 Zookeeper 相关概念和细节的…

【从零开始入门unity游戏开发之——C#篇12】新的引用类型——数组array

文章目录 一、数组&#xff08;array&#xff09;&#xff08;一维数组&#xff09;1、声明数组2、初始化数组3、访问数组元素4 、修改数组元素5、获取数组的长度6、遍历数组使用 for 循环&#xff1a;使用 foreach 循环&#xff1a; 7、数组方法排序&#xff1a;逆序&#xff…

9 OOM和JVM退出。OOM后JVM一定会退出吗?

首先我们把两个概念讲清楚 OOM是线程在申请堆内存&#xff0c;发现堆内存空间不足时候抛出的异常。 JVM退出的条件如下&#xff1a; java虚拟机在没有守护线程的时候会退出。守护线程是启动JVM的线程&#xff0c;服务于用户线程。 我们简单说下守护线程的功能: 1.日志的记录…

DeepSeek-AI 开源 DeepSeek-VL2 系列,采用专家混合(MoE)架构,重新定义视觉语言人工智能

将视觉与语言的智能融合&#xff0c;已经在视觉语言模型&#xff08;Vision-Language Models&#xff0c;简称VLMs&#xff09;领域实现了重大突破。这些模型致力于同步处理和解释视觉与文本数据&#xff0c;从而使得图像描述、视觉问题回答、光学字符识别&#xff08;Optical …