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

news2024/11/15 18:41:29

之前你可能经常听 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.coloradmin.cn/o/1439653.html

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

相关文章

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

百卓Smart管理平台 uploadfile.php 文件上传漏洞【CVE-2024-0939】 一、 产品简介二、 漏洞概述三、 影响范围四、 复现环境五、 漏洞复现手动复现小龙验证Goby验证 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工…

Python 线性回归可视化 并将回归函数放置到图像上

import matplotlib.pyplot as plt import scipy import seaborn as sns# 加载内置的数据集 df sns.load_dataset(tips)#create regplot p sns.regplot(xtotal_bill, ytip, datadf)#calculate slope and intercept of regression equation slope, intercept, r, p, sterr sci…

FlinkSql 窗口函数

Windowing TVF 以前用的是Grouped Window Functions(分组窗口函数),但是分组窗口函数只支持窗口聚合 现在FlinkSql统一都是用的是Windowing TVFs(窗口表值函数),Windowing TVFs更符合 SQL 标准且更加强大…

[项目管理] 如何使用git客户端管理gitee的私有仓库

最近发现即使翻墙也无法g使用ithub了,需要把本地的项目搬迁到新的git托管平台。 gitee 是一个国内开源项目托管平台,是开源开发者、团队、个人进行 git 代码管理和协作的首选平台之一。本文将详细介绍如何向 gitee 提交私有项目。 注册 Gitee 账号并创建…

AD域国产替代方案,助力某金融企业麒麟信创电脑实现“真替真用”

近期收到不少企业客户反馈采购的信创PC电脑用不起来,影响信创改造的进度。例如,某金融企业积极响应国产化信创替代战略,购置了一批麒麟操作系统电脑。分发使用中发现了如下问题: • 当前麒麟操作系统电脑无法做到统一身份认证&…

K8S系列文章之 [使用 Alpine 搭建 k3s]

官方文档:K3s - 轻量级 Kubernetes | K3s 官方描述,可运行在 systemd 或者 openrc 环境上,那就往精简方向走,使用 alpine 做系统。与 RHEL、Debian 的区别,主要在防火墙侧;其他基础配置需求类似&#xff0…

jmeter的简单使用

1、打开jmeter 打开Jmeter 安装包,进入\bin 中,找到“ApacheJMeter.jar”或"jmeter.bat", 双击打开即可 2、建立线程组 如下图所示,右击TestPlan,点击ADD->Threads(Users)->ThreadGroup 线程组页面分析&#xf…

IS-IS 接口认证密码平滑更换

拓扑图 配置 AR1、AR2建立ISIS level-2邻居关系,并配置接口认证密码为huawei sysname AR1 # isis 1is-level level-2network-entity 49.0000.0000.0000.0001.00 # interface GigabitEthernet0/0/0ip address 12.1.1.1 255.255.255.0 isis enable 1isis authentica…

ThinkPHP 中使用Redis

环境.env [app] app_debug "1" app_trace ""[database] database "" hostname "127.0.0.1" hostport "" password "" prefix "ls_" username ""[redis] hostname "127.0.0.1…

【C语言】通过socket看系统调用过程

一、通过socket看系统调用过程 在Linux操作系统中,系统调用是用户空间与内核空间之间交互的一种方式。当一个应用程序需要执行操作系统级别的任务时,比如创建一个网络套接字(socket),它必须通过系统调用请求内核来执行…

SQL在云计算中的新角色:重新定义数据分析

文章目录 1. 云计算与数据分析的融合2. SQL在云计算中的新角色3. 分布式SQL查询引擎4. SQL-on-Hadoop解决方案5. SQL与其他数据分析工具的集成6. 实时数据分析与SQL7. SQL在云数据仓库中的角色8. 安全性与隐私保护9. SQL的未来展望《SQL数据分析实战(第2版&#xff…

Snipaste使用

今天推荐一款好用的截图、贴图软件工具,名字叫Snipaste,以下是官方介绍的截图 软件官方下载地址: Snipaste 下载 1、截图功能 2、标注 3、开发中的使用 有时候在开发中需要临时把一些任务规则信息,放在代码编辑器旁边进行参考&am…

蓝桥杯每日一解

可以看看a的ascii码为6532 而A为ascii码为65&#xff0c;大小写相差32位 #include <iostream>using namespace std; int main(){int n;cin >> n;char a;for (int i 1;i<n;i){while(scanf("%c",&a) ! EOF){//无限输入直到输入到空格if(a a || a …

【多模态大模型】GLIP:零样本学习 + 目标检测 + 视觉语言大模型

GLIP 核心思想GLIP 对比 BLIP、BLIP-2、CLIP 主要问题: 如何构建一个能够在不同任务和领域中以零样本或少样本方式无缝迁移的预训练模型&#xff1f;统一的短语定位损失语言意识的深度融合预训练数据类型的结合语义丰富数据的扩展零样本和少样本迁移学习 效果 论文&#xff1a;…

OpenShift AI - 运行欺诈检测模型和流程

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在 OpenShift 4.14 RHODS 2.50 的环境中验证 文章目录 准备运行环境安装 OpenShift AI 环境安装 Minio 对象存储软件创建 Data Science Project创建 Data connection创建 Workbench配置 Model server创建 …

python调用golang中函数方法

一、原因说明&#xff1a;由于simhash方法有多种实现方式&#xff0c;现python中simhash方法与golang中的不一样&#xff0c;需要两者代码生成结果保持一致&#xff0c;故采用python中的代码调用golang编译的so文件来实现。 环境配置&#xff1a;①Windows10系统要有gcc环境&a…

【Git版本控制 03】远程操作

目录 一、克隆远程仓库 二、推送远程仓库 三、拉取远程仓库 四、忽略特殊文件 五、命令配置别名 一、克隆远程仓库 Git是分布式版本控制系统&#xff0c;同⼀个Git仓库&#xff0c;可以分布到不同的机器上。怎么分布呢&#xff1f; 找⼀台电脑充当服务器的⻆⾊&#xff…

幻方(Magic Square)

幻方&#xff08;Magic Square&#xff09; 幻方概述 什么是幻方呢&#xff1f;幻方&#xff08;Magic Square&#xff09;就是指在nn&#xff08;n行n列&#xff09;的方格里填上一些连续的数字&#xff0c;使任意一行、任意一列和对角线上的数字的和都相等。例如有33的3行3…

【操作系统】MacOS虚拟内存统计指标

目录 命令及其结果 参数解读 有趣的实验 在 macOS 系统中&#xff0c;虚拟内存统计指标提供了对系统内存使用情况和虚拟内存操作的重要洞察。通过分析这些指标&#xff0c;我们可以更好地了解系统的性能状况和内存管理情况。 命令及其结果 >>> vm_stat Mach Virtu…

电力负荷预测 | 基于TCN的电力负荷预测(Python)———数据预处理

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 基于TCN的电力负荷预测(Python) python3.8 keras2.6.0 matplotlib3.5.2 numpy1.19.4 pandas1.4.3 tensorflow==2.6.0