undo log

从这篇「执行一条 SQL 查询语句,期间发生了什么? (opens new window)」中,我们知道了一条查询语句经历的过程,这属于「读」一条记录的过程,如下图:

查询语句执行流程

那么,执行一条 update 语句,期间发生了什么?,比如这一条 update 语句:

UPDATE t_user SET name = 'xiaolin' WHERE id = 1;

查询语句的那一套流程,更新语句也是同样会走一遍:

  • 客户端先通过连接器建立连接,连接器自会判断用户身份;
  • 因为这是一条 update 语句,所以不需要经过查询缓存,但是表上有更新语句,是会把整个表的查询缓存清空的,所以说查询缓存很鸡肋,在 MySQL 8.0 就被移除这个功能了;
  • 解析器会通过词法分析识别出关键字 update,表名等等,构建出语法树,接着还会做语法分析,判断输入的语句是否符合 MySQL 语法;
  • 预处理器会判断表和字段是否存在;
  • 优化器确定执行计划,因为 where 条件中的 id 是主键索引,所以决定要使用 id 这个索引;
  • 执行器负责具体执行,找到这一行,然后更新。

不过,更新语句的流程会涉及到 undo log(回滚日志)、redo log(重做日志) 、binlog (归档日志)这三种日志:

  • undo log(回滚日志):是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC
  • redo log(重做日志):是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于掉电等故障恢复
  • binlog (归档日志):是 Server 层生成的日志,主要用于数据备份和主从复制

所以这次就带着这个问题,看看这三种日志是怎么工作的。

为什么需要 undo log?

我们在执行执行一条“增删改”语句的时候,虽然没有输入 begin 开启事务和 commit 提交事务,但是 MySQL 会隐式开启事务来执行“增删改”语句的,执行完就自动提交事务的,这样就保证了执行完“增删改”语句后,我们可以及时在数据库表看到“增删改”的结果了。

执行一条语句是否自动提交事务,是由 autocommit 参数决定的,默认是开启。所以,执行一条 update 语句也是会使用事务的。

那么,考虑一个问题。一个事务在执行过程中,在还没有提交事务之前,如果 MySQL 发生了崩溃,要怎么回滚到事务之前的数据呢?

如果我们每次在事务执行过程中,都记录下回滚时需要的信息到一个日志里,那么在事务执行中途发生了 MySQL 崩溃后,就不用担心无法回滚到事务之前的数据,我们可以通过这个日志回滚到事务之前的数据。

实现这一机制就是 undo log(回滚日志),它保证了事务的 ACID 特性 (opens new window)中的原子性(Atomicity)

undo log 是一种用于撤销回退的日志。在事务没提交之前,MySQL 会先记录更新前的数据到 undo log 日志文件里面,当事务回滚时,可以利用 undo log 来进行回滚。如下图:

回滚事务

每当 InnoDB 引擎对一条记录进行操作(修改、删除、新增)时,要把回滚时需要的信息都记录到 undo log 里,比如:

  • 插入一条记录时,要把这条记录的主键值记下来,这样之后回滚时只需要把这个主键值对应的记录删掉就好了;
  • 删除一条记录时,要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入到表中就好了;
  • 更新一条记录时,要把被更新的列的旧值记下来,这样之后回滚时再把这些列更新为旧值就好了。

在发生回滚时,就读取 undo log 里的数据,然后做原先相反操作。比如当 delete 一条记录时,undo log 中会把记录中的内容都记下来,然后执行回滚操作的时候,就读取 undo log 里的数据,然后进行 insert 操作。

不同的操作,需要记录的内容也是不同的,所以不同类型的操作(修改、删除、新增)产生的 undo log 的格式也是不同的,具体的每一个操作的 undo log 的格式我就不详细介绍了,感兴趣的可以自己去查查。

一条记录的每一次更新操作产生的 undo log 格式都有一个 roll_pointer 指针和一个 trx_id 事务id:

  • 通过 trx_id 可以知道该记录是被哪个事务修改的;
  • 通过 roll_pointer 指针可以将这些 undo log 串成一个链表,这个链表就被称为版本链;

版本链如下图:

版本链

另外,undo log 还有一个作用,通过 ReadView + undo log 实现 MVCC(多版本并发控制)

对于「读提交」和「可重复读」隔离级别的事务来说,它们的快照读(普通 select 语句)是通过 Read View + undo log 来实现的,它们的区别在于创建 Read View 的时机不同:

  • 「读提交」隔离级别是在每个 select 都会生成一个新的 Read View,也意味着,事务期间的多次读取同一条数据,前后两次读的数据可能会出现不一致,因为可能这期间另外一个事务修改了该记录,并提交了事务。
  • 「可重复读」隔离级别是启动事务时生成一个 Read View,然后整个事务期间都在用这个 Read View,这样就保证了在事务期间读到的数据都是事务启动前的记录。

这两个隔离级别实现是通过「事务的 Read View 里的字段」和「记录中的两个隐藏列(trx_id 和 roll_pointer)」的比对,如果不满足可见行,就会顺着 undo log 版本链里找到满足其可见性的记录,从而控制并发事务访问同一个记录时的行为,这就叫 MVCC(多版本并发控制)。具体的实现可以看我这篇文章:事务隔离级别是怎么实现的?(opens new window)

因此,undo log 两大作用:

  • 实现事务回滚,保障事务的原子性。事务处理过程中,如果出现了错误或者用户执 行了 ROLLBACK 语句,MySQL 可以利用 undo log 中的历史数据将数据恢复到事务开始之前的状态。
  • 实现 MVCC(多版本并发控制)关键因素之一。MVCC 是通过 ReadView + undo log 实现的。undo log 为每条记录保存多份历史数据,MySQL 在执行快照读(普通 select 语句)的时候,会根据事务的 Read View 里的信息,顺着 undo log 的版本链找到满足其可见性的记录。

TIP

很多人疑问 undo log 是如何刷盘(持久化到磁盘)的?

undo log 和数据页的刷盘策略是一样的,都需要通过 redo log 保证持久化。

buffer pool 中有 undo 页,对 undo 页的修改也都会记录到 redo log。redo log 会每秒刷盘,提交事务时也会刷盘,数据页和 undo 页都是靠这个机制保证持久化的。

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

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

相关文章

桌面显示器PD芯片:引领桌面显示技术的新篇章

随着科技的飞速发展,桌面显示器作为人们日常工作与生活中不可或缺的重要设备,其性能与品质也在不断提升。其中,PD芯片作为桌面显示器中的核心组件,发挥着至关重要的作用。本文将对桌面显示器PD芯片进行详细介绍,探讨其…

MD5源码(C语言描述)

本文介绍MD5源码(C语言描述)。 MD5(Message-Digest Algorithm 5),即消息摘要算法5,是一种被广泛使用的消息散列算法。散列算法的基础原理是:将数据(如一段文字)经过运算转换为一段固定长度&…

#Linux(VMwareTOOL安装)

(一)发行版:Ubuntu16.04.7 (二)记录: (1) (2)打开虚拟机然后安装,出现灰色可能是已经安装过但是自己没有找到 (3)删除VM…

流畅切换Linux的应用程序

流畅切换Linux的应用程序 流畅切换Linux的应用程序一.Linux启动一个程序在后台执行1. 使用nohup和&:2. 使用ctrlZ:3.使用screen:3.1 创建会话3.2 要重新连接到此会话:3.3 中途退出会话,但程序继续运行:3.4 结束一个…

STM32的简单介绍

STM32是一种基于ARM Cortex-M内核的32位微控制器,由意法半导体公司开发和生产。STM32具有丰富的外设和功能,适用于各种应用场合,如工业控制、消费电子、物联网、人机交互等。STM32的优势包括低功耗、高性能、高可靠性、易于开发等。STM32的系…

上海晋名室外暂存柜助力新技术皮革制品生产行业安全

本周上海晋名又有一台室外危化品暂存柜项目通过验收,此次项目主要用于新技术皮革制品生产行业油桶、化学品等物资的室外暂存安全。 用户单位创立于2004年,是一家从事新技术皮革制品加工、生产的外资企业。 上海晋名作为一家专注工业安全防护领域&#…

基于消失点的相机自标定

基于消失点的相机自标定 附赠最强自动驾驶学习资料:直达链接 相机是通过透视投影变换来将3D场景转换为2D图像。在射影变换中,平行线相交于一点称之为消失点。本文详细介绍了两种利用消失点特性的标定方法。目的是为根据实际应用和初始条件选择合适的标…

SpingBoot集成Rabbitmq及Docker部署

文章目录 介绍RabbitMQ的特点Rabbitmq术语消息发布接收流程 Docker部署管理界面说明Overview: 这个页面显示了RabbitMQ服务器的一般信息,例如集群节点的名字、状态、运行时间等。Connections: 在这里,可以查看、管理和关闭当前所有的TCP连接。Channels: …

component-右侧抽屉组件

1.右侧抽屉组件 点击筛选&#xff0c;右侧抽屉滑出&#xff0c;点击取消或者点击空白处抽屉收起。 2.代码 <template><div class"all" click"hidden()"><!-- 抽屉 --><div class"drawer"><div class"drawerBo…

js处理数组分类

const obj [{"groupingType": "1","remark": "梨花带雨","totalRmbMoney": 7,"kyeGroupingType": "广州一组"},{"groupingType": "2","remark": "99","…

【蓝桥杯】第15届蓝桥杯青少组stema选拔赛C++中高级真题答案(20240310)

一、选择题 第 1 题 第 2 题 表达式1000/3的结果是( A )。 A.333 B.333.3 C.334 D.333.0 第 3 题 下列选项中&#xff0c;判断a等于1并且b等于1正确的表达式是( B )。 A.!((a!1)&&(b!1)) B.!((a!1)||(b!1)) C.!(a1)&&(b1) D.(a1)&&(b1) 【解析】 A…

测试用例设计指南

软件测试设计是测试过程中重要的测试活动&#xff0c;怎么样设计测试用例能提高我们测试的效率和质量&#xff0c;从以下几个方面做了简单的讲解。 1 测试用例设计原则 测试用例设计的基本原则包括&#xff1a;有效性、清晰性、可复用性、可维护性、完整性、兼容性、易操作性…

【数据可视化】Echarts官方文档及常用组件

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. Echarts官方文档介绍3. ECharts基础架构及常用术语3.1 ECharts的基础架构3.2 ECharts的常用术语3.2.1 ECharts的基本名词3.2.2 ECharts的图表名词 4. 直角坐标系下的网格及坐标轴4.1 直角坐标系下的网格4.2…

360企业安全浏览器兼容模式显示异常某个内容不显示 偶发现象 本地无法复现情况js

360企业安全浏览器兼容模式显示异常 &#xff0c;现象测试环境频发 &#xff0c;本地连测试无法复现&#xff0c;线上反馈问题。 出现问题的电脑为windows且使用360企业安全浏览器打开兼容模式可复现 复现过程&#xff1a; 不直接点击超链接跳转页面 &#xff0c;登录后直接通…

vue3+threejs新手从零开发卡牌游戏(三):尝试在场景中绘制一张卡牌

首先我们思考下&#xff0c;一张最简单的卡牌有哪些东西构成&#xff1a;卡牌样式和卡牌数据。一张卡牌有正面和背面&#xff0c;有名称、属性、种族、攻击力等数据&#xff0c;我们先不考虑数据&#xff0c;先尝试在场景中绘制一张卡牌出来。 一、寻找卡牌素材 为了简单我直…

【考研数学】如何打牢基础?刷1800/1000/880/660还是教材?

如果想要用课后题来复习的话&#xff0c;可以从网上找一份复习题单来对照着做&#xff0c;这样可以把一些非重点内容忽略过去&#xff0c;提高我们复习的效率。 如果备考考研数学的话&#xff0c;专门的练习册更好一些。因为课后习题同类型的题目比较少&#xff0c;对于总结能…

持续领跑!腾讯云NDR再获Gartner®认可

近日&#xff0c;国际研究机构Gartner发布《Competitive Landscape&#xff1a;Network Detection and Response》&#xff08;以下简称“报告”&#xff09;&#xff0c;腾讯被列为NDR案例厂商&#xff08;NDR for SaaS and Cloud Identity Applications&#xff09;。 腾讯云…

需求:JSON数据显示null值或者不显示null值

使用hutool的工具类 import cn.hutool.json.JSON; import cn.hutool.json.JSONConfig; import cn.hutool.json.JSONUtil;public class Main {public static void main(String[] args) {String sss "{\"1\":\"a\",\"2\":null}";// 不…

【vue-小知识】var、let 和 const之间的区别

文章目录 结论1、重复定义变量名var&#xff1a;允许重复定义变量名let和const&#xff1a;不可以重复定义变量名 2、修改值var&#xff1a;允许修改值let&#xff1a;允许修改值const&#xff1a;不允许修改值&#xff0c;会报错 3、变量提升var : 支持变量提升let和const&…

程序猿成长之路之番外篇——矩阵算法

今天在复习线性代数知识的过程中&#xff0c;用java语言简单实现了一下矩阵算法。 数学知识回顾 1.什么是矩阵 在数学领域&#xff0c;矩阵就像一个表格&#xff0c;将数据排放进去&#xff0c;形成一个矩形。我们习惯用一个大括号把矩阵内的数据包括进来。 1.矩阵 在数学领域…