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

之前你可能经常听 DBA 同事说,MySQL 可以恢复到半个月内任意一秒的状态,惊叹的同时,你是不是心中也会不免会好奇,这是怎样做到的呢?

我们先从一条更新语句讲起,首先创建一个表,这个表有一个主键ID,和一个整形的value

mysql> create table T(ID int primary key, c int);

更新ID=2的记录,将它的value+1

mysql> update T set c=c+1 where ID=2;

更新语句和前面的查询语句一样,会经过连接器、分析器、优化器、执行器等一系列操作。

但是更新语句和查询也有不同的地方,那就是日志模块redo log(重做日志)和 binlog(归档日志)

2.1redo log

MySQL每一次的更新操作都需要写入进磁盘,在磁盘中找到对应的记录进行更新,整个IO操作的成本很高,为了解决这个问题就出现了redo log这种临时记事本的形式来提升效率。

而这个临时记事本的过程就是MySQL里经常说到的WAL技术,WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘,也就是先写粉板,等不忙的时候再写账本。

具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log(粉板)里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做,这就像打烊以后掌柜做的事

InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么这块“粉板”总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写,如下面这个图所示。

在这里插入图片描述

write pos就是当前记录更新的位置,它不断的往前写,check point是当前要擦除的位置,它也会不断的向前。write pos碰到check point后就会停下来,这时候就要先擦一些记录,让check point往前移动,腾出一些空间来记录redo log

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

2.2binlog

MySQL整体就2块,一块是Server层,一块是存储引擎层,redo log 是innoDB存储引擎的日志,binlog是Server层的日志。

为什么有2份日志呢?

因为最开始MySQL是没有innoDB引擎的,MyISAM才是MySQL自带的引擎,但是MyISAM没有crash-safe的能力。这时候出现了innoDB,它是其它公司开发的,以插件的形式引入到MySQL中,因为binlog只能用于归档,所以它们开发了一套新的日志系统—— redo log

这两种日志有以下三点不同。

  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)状态,更新完成。

在这里插入图片描述

为什么必须有“两阶段提交”呢?这是为了让两份日志之间的逻辑一致。

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

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

相关文章

百卓Smart管理平台 uploadfile.php 文件上传漏洞(CVE-2024-0939)

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…

零基础学Python(9)— 流程控制语句(下)

前言:Hello大家好,我是小哥谈。流程控制语句是编程语言中用于控制程序执行流程的语句,本节课就带大家认识下Python语言中常见的流程控制语句!~🌈 目录 🚀1.while循环 🚀2.for循环 &#x1…

RCE(命令执行)知识点总结最详细

description: 这里是CTF做题时常见的会遇见的RCE的漏洞知识点总结。 如果你觉得写得好并且想看更多web知识的话可以去gitbook.22kaka.fun去看,上面是我写的一本关于web学习的一个gitbook,当然如果你能去我的github为我的这个项目点亮星星我会感激不尽htt…

STM32之定时器

一、简介 STM32F4xx系列共有14个定时器,其中2个高级定时器、10个通用定时器、2个基本定时器。下图 为各定时器及其功能。 图1.各定时器及其功能 二、定时器的计数模式 向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始…

17:定时器编程实战

1、实验目的 (1)使用定时器来完成LED闪烁 (2)原来实现闪烁时中间的延迟是用delay函数实现的,在delay的过程中CPU要一直耗在这里不能去做别的事情。这是之前的缺点 (3)本节用定时器来定一个时间(譬如0.3s),在这个定时器定时时间内…

抽象springBoot报错

Failed to configure a DataSource: url attribute is not specified and no embedded datasource could be configured. 中文翻译:无法配置DataSource:未指定“url”属性,并且无法配置嵌入数据源。 DataSource 翻译:数据源 得…

The Back-And-Forth Method (BFM) for Wasserstein Gradient Flows windows安装

本文记录了BFM算法代码在windows上的安装过程。 算法原网站:https://wasserstein-gradient-flows.netlify.app/ github:https://github.com/wonjunee/wgfBFMcodes 文章目录 FFTWwgfBFMcodesMATLABpython注 FFTW 官网/下载路径:https://ww…

警惕钓鱼邮件,保护您的开发者账号

请警惕钓鱼邮件 钓鱼邮件经常冒充官方 Google Play 通信,以窃取敏感信息,并最终为了经济利益盗取开发者账号。 保护开发者免受钓鱼邮件侵害的提示: Google.com 是用于联系开发者的唯一合法电子邮件域名。我们不会通过电子邮件或实时聊天要求您…

【Linux系统学习】 4.Linux实用操作 上

Linux实用操作 1.各类小技巧(快捷键) 1.1 ctrl c 强制停止 Linux某些程序的运行,如果想要强制停止它,可以使用快捷键ctrl c 命令输入错误,也可以通过快捷键ctrl c,退出当前输入,重新输入 1…

第十六篇【传奇开心果系列】Python的OpenCV库技术点案例示例:图像质量评估

传奇开心果短博文系列 系列短博文目录Python的OpenCV库技术点案例示例短博文系列博文目录前言一、图像质量评估方法和相关函数的介绍二、均方误差示例代码三、峰值信噪比示例代码四、结构相似性指数示例代码五、视频质量评估示例代码六、OpenCV均方根误差计算示例代码七、OpenC…

Cilium CNI深度指南

Cilium是基于eBPF的功能强大的CNI插件,为云原生环境提供了强大的网络和安全支持。原文: Cilium CNI: A Comprehensive Deep Dive Guide for Networking and Security Enthusiasts! 🌓简介 欢迎阅读为网络和安全爱好者提供的全面深入的指南! 本…

【JavaEE】_传输层协议UDP与TCP

目录 1. 开发中常见的数据组织格式 1.1 XML 1.2 JSON 1.3 Protobuf 2. 端口号 3. UDP协议 4. TCP协议 4.1 特点 4.2 TCP报文格式 4.3 TCP可靠性机制 4.3.1 确认应答机制 4.3.2 超时重传机制 4.3.2.1 丢包的两种情况 4.3.2.2 重传时间 4.3.3 连接管理机制 4.3.3…

VSCode如何让先前打开的文件不被自动关闭,一直保持在标签栏里(关闭预览模式)

第一次接触VSCode-Huawei IDE编辑器,每次打开一个新的代码文件,旧的代码文件都会被自动关闭(现在才知道是因为文件默认是以预览模式打开展示的)。 那么如何才能让先前打开的文件一直保持在标签栏里呢? 我们需要去设置…

MySQL 升级脚本制作

当数据库更新字段后或添加一些基础信息,要对生产环境进行升级,之前都是手动编写sql,容易出错还容易缺失。 通过 Navcat 工具的数据库结构同步功能和数据同步功能完成数据库脚本的制作。 一、结构同步功能 1、选择 工具–结构同步&#xff1…

【项目技术点总结之三】使用Java生成复杂好看的word或pdf报告的解决方案

前言 项目中往往会遇到需要生成报告的场景,不管是简单报告还是复杂报告,其实都需要找很多资料去尝试,本文会提出几种个人完美解决报告生成的解决方案,而且会提出几个失败但是能生成报告的设想,当然都是踩过坑的&#…

Web3智能合约:重新定义商业合作的未来

随着区块链技术的飞速发展,Web3时代正逐渐到来,而其中的智能合约成为推动商业合作变革的关键力量。本文将深入探讨Web3智能合约的概念、特点以及对商业合作未来的巨大影响。 什么是Web3智能合约? 智能合约是一种以代码形式编写、自动执行合同…

Linux——进程间通信:管道

我们在开发过程中,可能会碰到两个或多个进程需要协同进行,这两个进 程之间有着一定的关系,这个进程可能会需要另一个进程的某些消息来达 到自己的目的,或者是一个进程控制着另一个进程,又或者是需要某种资 源的共享。但…

Blazor入门100天 : 自做一个支持长按事件的按钮组件

好长时间没继续写这个系列博客了, 不知道大家还记得我吗? 话不多说,直接开撸. 配套源码 demo https://blazor.app1.es/b19LongPressButton ####1. 新建 net8 blazor 工程 b19LongPressButton 至于用什么模式大家各取所需, 我创建的是ssr单工程, 如果大家不小心建立错了按页…

C#上位机与三菱PLC的通信03--MC协议之A-1E报文解析

1、MC协议帧 MC协议可以在串口通信,也可以在以太网通信,有A-1E和Qna-3E两种模式,这两种都是三菱PLC通信协议中比较常用的两种,一般我们使用比较多的是以太网通信,对于FX5U系列/Q系列/Qna系列/L系列的PLC,…

深度学习入门笔记(八)可以不断思考的模型:RNN与LSTM

8.1 循环神经网络RNN 之前学到的 CNN 和全连接,模型的输入数据之间是没有关联的,比如图像分类,每次输入的图片与图片之间就没有任何关系,上一张图片的内容不会影响到下一张图片的结果。但在自然语言处理领域,这就成了…