一条 SQL 更新语句如何执行的

    Server 层
    存储引擎层
    总流程
        查询语句
            连接器
            查询缓存
            分析器
            优化器
            执行器
        更新语句
            redo log(节省的是随机写磁盘的 IO 消耗(转成顺序写))
                InnoDB 引擎
                物理日志
                循环写
            binlog
                server层
                逻辑日志
                追加写入
            两阶段提交

为了知道,mysql 中一条 sql 语句是如何执行的,先讲一下 mysql 的宏观分层以及如何执行查询语句.

 MySQL 宏观上分为 Server 层存储引擎层, MySQL 通过 server 层调用存储引擎层操作数据返回结果,Server 层又可以分为

  1. 连接器
  2. 分析器
  3. 优化器
  4. 执行器

连接器负责跟客户端建立连接、获取权限、维持和管理连接。

分析器先会做“词法分析”。你输入的是由多个字符串和空格组成的一条 SQL 语句,MySQL 需要识别出里面的字符串分别是什么,代表什么。做完了这些识别以后,就要做“语法分析”。根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。

优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。 

执行器会根据表的引擎定义,去使用这个引擎提供的接口。示例:

mysql> select * from T where ID=10;

比如我们这个例子中的表 T 中,ID 字段没有索引,那么执行器的执行流程是这样的:

  1. 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;
  2. 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
  3. 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

至此,这个语句就执行完成了。


查询语句的那一套流程,更新语句也是同样会走一遍。与查询流程不一样的是,更新流程还涉及两个重要的日志模块,它们正是我们今天要讨论的主角:redo log(重做日志)和 binlog(归档日志)

redo log

如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。

当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面。

InnoDB 的 redo log 是固定大小的,满了时不能再执行新的更新。由参数 innodb_log_file_size  innodb_log_files_in_group 决定。

有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。 

change buffer

当需要更新一个数据页时,如果数据页在内存中就直接更新,而如果这个数据页还没有在内存中的话,InnoDB 会将这些更新操作缓存在 change buffer 中,这样就不需要从磁盘中读入这个数据页了。在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行 change buffer 中与这个页有关的操作。change buffer 在内存中有拷贝,也会被写入到磁盘上。

将 change buffer 中的操作应用到原数据页,得到最新结果的过程称为 merge。除了访问这个数据页会触发 merge 外,系统有后台线程会定期 merge。在数据库正常关闭(shutdown)的过程中,也会执行 merge 操作。

change buffer 用的是 buffer pool 里的内存,因此不能无限增大。change buffer 的大小,可以通过参数 innodb_change_buffer_max_size 来动态设置。这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%。

因为 merge 的时候是真正进行数据更新的时刻,而 change buffer 的主要目的就是将记录的变更动作缓存下来,所以在一个数据页做 merge 之前,change buffer 记录的变更越多(也就是这个页面上要更新的次数越多),收益就越大。因此,对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时 change buffer 的使用效果最好。 

binlog

redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(归档日志).这两种日志有以下三点不同。

  1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  2. redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
  3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

执行器和 InnoDB 引擎在执行这个简单的 update 语句时的内部流程: 

  1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
  2. 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
  3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
  4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
  5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。

将 redo log 的写入拆成了两个步骤:prepare 和 commit,这就是"两阶段提交"。 

推荐阅读

一条 SQL 更新语句如何执行的 

MySQL 事务的原理以及长事务的预防和处置 

InnoDB索引优化 

一条 sql 语句可能导致的表锁和行锁以及死锁检测 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

骨传导耳机领头羊——南卡在AWE2024展会上展现强大的创新实力

在2024年的AWE(中国家电及消费电子博览会)上,南卡凭借其尖端的骨传导耳机技术再次成为业界瞩目的中心。作为骨传导技术的先驱和领航者,南卡不仅展出了其最新的产品,更向世界宣布了其在开放式耳机市场的宏伟蓝图。 南卡…

java零基础入门-Map集合练习(上)

一、教学目标 能够使用HashMap集合实现值为双列集合存放。能够使用HashMap集合实现值为单列集合存放。能够使用HashMap集合实现值为基本数据类型存放。能够使用HashMap集合实现值为对象存放。... 二、HashMap实现自定义元素存放 1、值存放基本数据类型 像这中就非常简单了呀…

损失函数和反向传播

1. 损失函数的基础 import torch from torch.nn import L1Loss from torch import nninputs torch.tensor([1, 2, 3], dtypetorch.float32) targets torch.tensor([1, 2, 5], dtypetorch.float32)inputs torch.reshape(inputs, (1, 1, 1, 3)) targets torch.reshape(targe…

迄今为止易用 —— 的 “盲水印“ 实现方案

前期回顾 网站的打赏 —— 新一代的思路-CSDN博客https://blog.csdn.net/m0_57904695/article/details/136704914?spm1001.2014.3001.5501 目录 CSDN 彩色之外 📝 前言: 🛠️ vue3-blind-watermark 🤖 安装 ♻️ 引入&am…

Jmeter入参问题小记

表单入参的时候,这个地方需要勾选,如果不☑️选的话,会提示errorMsg":"Required String parameter code is not present",

【面试精讲】String是如何实现的?String源码分析

【面试精讲】String是如何实现的?String源码分析 目录 一、String实现机制 二、String不可变性(使用final修饰) 三、String 和 StringBuilder、StringBuffer 的区别 四、和equals的区别 五、String创建对象与JVM辨析 六、String源码解…

Spring Web MVC入门(1)

什么是Spring Web MVC? 定义:Spring Web MVC是基于Servlet构建的原始Web框架,从一开始就包含在Spring框架中.它的正式名称"Spring Web MVC"来自其源模块的名称(Spring-webmvc),但是它通常被称为"Spring MVC". 什么是Servlet? Servlet是一种实现动态页面…

springboot+ssm基于vue.js的客户关系Crm管理系统

系统包含两种角色:管理员、用户,主要功能如下。 ide工具:IDEA 或者eclipse 编程语言: java 数据库: mysql5.7 框架:ssmspringboot都有 前端:vue.jsElementUI 详细技术:springbootSSMvueMYSQLMAVEN 数据库…

电梯机房秀

每天乘坐电梯,您见过电梯的机房吗?来,跟着小伍去看看吧。Lets go! 电梯还能节能呢,您知道么?正好,小伍一块带您看看电梯节能装置(●◡●) 目前电梯节能装置已广泛应用于三菱、富士、日立、奥的斯…

案例分析篇12:可靠性设计考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

深入理解 CSS——CSS进阶与实践(5w字高频面试题整理)

本文总结了CSS高频面试题,并搭配了演示动画进行CSS样式演示。介绍了关于如何理解盒模型,如何实现块级元素水平居中,如何实现两侧固定中间自适应的三栏布局、如何实现两栏布局,如何进行响应式设计,对BFC的理解&#xff…

Github上哪些好用的安全工具1

专注于web漏洞挖掘、内网渗透、免杀和代码审计,感谢各位师傅的关注!网安之路漫长,与君共勉! URLFinder 一款快速提取网页信息的工具。该项目可以快速爬取网页上的 URL 地址、JS 文件里的 API 接口等信息,支持批量抓取…

市场复盘总结 20240314

仅用于记录当天的市场情况,用于统计交易策略的适用情况,以便程序回测 短线核心:不参与任何级别的调整,采用龙空龙模式 一支股票 10%的时候可以操作, 90%的时间适合空仓等待 二进三: 进级率中 25% 最常用的…

【CSP试题回顾】201703-2-学生排队

CSP-201703-2-学生排队 解题思路 初始化队列:通过输入获得学生的数量 n,然后创建一个队列 queue,初始时这个队列中的学生按照学号从小到大的顺序排列。这是通过循环赋值实现的,其中每个学生的学号是其在列表中的位置加1。 处理调…

男人圣经 7

男人圣经 7 高逼格长期目标的行动飞轮1. 品牌价值和声誉2. 人脉网络和关系3. 企业文化和价值观4. 专有技术和知识产权5. 管理经验和专业知识 为什么只追求高经济、高科技?为什么说道德仁义是表面,而利益才是一切背后的真相? 高逼格长期目标的…

SinoDB数据库资源分析

SinoDB数据库资源主要从数据库虚处理器繁忙状况、数据库虚拟内存段、锁资源使用情况、数据空间使用率、网络连接情况等5个方面来进行分析。分别如下: 一、数据库虚处理器 检查项目 数据库虚处理器繁忙状况 检查命令 onstat -g rea onstat -g glo 说明 1、使用ons…

中科数安|公司办公终端、电脑文件数据 \ 资料防泄密系统

#中科数安# 中科数安是一家专注于信息安全技术与产品研发的高新技术企业,其提供的公司办公终端、电脑文件数据及资料防泄密系统(也称为终端数据防泄漏系统或简称DLP系统)主要服务于企业对内部敏感信息的安全管理需求。 www.weaem.com 该系统…

01、JS实现:去除数组中重复项的算法之一

数组去除重复项的算法: Ⅰ、删除排序数组中的重复项(注意:是已经排好序的):1、题目描述:2、解题思路:3、实现代码: Ⅳ、小结: Ⅰ、删除排序数组中的重复项(注意:是已经排好序的)&…

ConcurrentHashMap 为什么不能插入 null?

1、典型回答 简单来说,ConcurrentHashMap 不允许插入 null 值是JDK 源码规定的,如下源码所示(此源码基于JDK 1.8): 从上述源码可以看出,在添加方法的第一句就加了判断:如果 key 值为 null 或者是 value 值为 null&…

齐聚“向上的力量”,维谛技术(Vertiv)2024年合作伙伴大会成功举办

3月13日,维谛技术(Vertiv,NYSE:VRT)2024年合作伙伴大会在广东佛山顺利召开,本次大会以“向上的力量”为主题,维谛技术与数百家优秀合作伙伴(含港台)欢聚一堂,…