MySQL进阶之(十二)MySQL事务日志-undo log

十二、MySQL事务日志-undo log

  • 12.1 undo log 引入
  • 12.2 undo log 的作用
    • 01、回滚数据
    • 02、MVCC
  • 12.3 undo log 的存储结构
    • 01、回滚段与 undo 页
    • 02、回滚段与事务
    • 03、回滚段中的数据分类
  • 12.4 undo log 的类型
  • 12.5 undo log 的生命周期
    • 01、执行 insert 操作
    • 02、执行 update 操作
    • 03、执行 delete 操作
  • 12.3 小结

redo log 是事务持久性的保证,undo log 是事务原子性的保证。在事务中更新数据的前置操作其实就是要先写入一个 undo log。

12.1 undo log 引入

事务需要保证原子性,也就是说,事务中的操作要么全部成功,要么全部失败。但是有时候事务执行到一半的时候会出现一些情况:

  • 情况一:事务执行过程中可能遇到各种错误,比如服务器本身的错误、操作系统的错误、甚至突然断电导致的错误等等。
  • 情况二:在事务执行的过程中手动执行 rollback 语句结束当前事务的操作。

一旦出现以上的情况,就需要把数据恢复成原先的样子,这个过程就是 "回滚",这样就可以造成一个假象:这个事务看起来什么都没做,所以符合原子性的要求。

所以,需要重点关注的就是如何 “回滚”:

当我们对一条数据做改动时(这里的改动可以是 insert、delete、update),就把回滚时所需的东西记录下来。

  • 插入一条记录时,至少要把这条记录的主键值记录下来,之后回滚的时候只需要把这个主键值对于的记录删除掉就可以了(对于每个 insert,InnoDB 存储引擎会完成一个 delete)。
  • 删除一条记录时,至少要把这条记录中的内容都记录下来 ,之后回滚的时候再把由这些内容组成的记录插入到表中就可以了(对于每个 delete,InnoDB 存储引擎会执行一个 insert)。
  • 修改一条记录时,至少要把修改这条记录前的旧值都记录下来,之后回滚时再把这条记录更新为旧值就可以了(对于每个 update,InnoDB 存储引擎会执行一个相反的 update,将修改前的行放回去)。

MySQL 把这些为了回滚而记录的这些内容称之为撤销日志或回滚日志。由于查询操作并不会修改任务用户记录,所以在查询操作执行时,并不需要记录相应的 undo log。

另外需要注意的是:undo log 会产生 redo log,也就是 undo log 的产生会伴随着 redo log 的产生,这是因为 undo log 也需要持久性的保护。

12.2 undo log 的作用

01、回滚数据

undo log 是逻辑日志 ,只是将数据库逻辑地恢复到原来的样子。所有修改都被逻辑地取消了,但是数据结构和页本身在回滚之后可能大不相同 。

这是因为在多用户并发系统中,可能会有数十、数百甚至数千个并发事务。数据库的主要任务就是协调对数据记录的并发访问 。比如,一个事务在修改当前页中某几条记录,同时还有别的事务在对同一个页中另几条记录进行修改。因此,不能将一个页回滚到事务开始的样子,因为这样会影响其他事务正在进行的工作。

02、MVCC

undo log 的另一个作用是 MVCC,即在 InnoDB 存储引擎中 MVCC 的实现是通过 undo 来完成。当用户读取一行记录时,如果该记录已经被其他事务占用,当前事务可以通过 undo log 读取之前的行版本信息,以此实现非锁定读取。

12.3 undo log 的存储结构

01、回滚段与 undo 页

回滚段

InnoDB 对 undo log 的管理采用段的方式,也就是回滚段(rollback segment)。每个回滚段记录了 1024 个 undo log segment,而在每个 undo log segment 中进行 undo 页的申请。

在 InnoDB 1.1 版本之前(不包括 1.1 版本),只有一个 rollback segment,所以支持同时在线的事务限制为 1024,这对绝大多数的应用来说已经够用。

从 1.1 版本开始 InnoDB 支持最大 128 个 rollback segment,所以其支持同时在线的事务限制提高到了 128 * 1024。

undo 页的重用

当开启一个事务的时候,要先去 undo log segment 中找到一个空闲的位置,当有空位的时候,就去申请 undo 页,在这个申请到的 undo 页中进行 undo log 的写入,这一个页的默认大小是 16KB。

为每个事务分配一个页是非常浪费的(除非事务非常长),假设应用的 TPS(每秒处理的事务数目)为 1000,那么 1s 就需要 1000 个页,大概需要 16M 的存储,每分钟大概需要 1G 的存储。如果照这样下去,除非 MySQL 清理的非常勤快,否则随着时间的推移,磁盘空间会增长的非常快,而且很多空间都是浪费的。

于是 undo 页就设计的可以重用了,当事务提交时,并不会立刻删除 undo 页。因为重用,所以这个 undo 页可能混杂着其他事务的 undo log,undo log 在提交后,会被放到一个链表中,然后判断 undo 页的使用空间是否小于 3/4,如果小于 3/4 的话 ,则表示当前的 undo 页可以被重用,那么它就不会被回收,其他事务的 undo log 可以记录在当前 undo 页的后面。由于 undo log 是离散的,所以清理对应的磁盘空间时,效率不高。

02、回滚段与事务

  • 每个事务只会使用一个回滚段,一个回滚段在同一时刻可能会服务于多个事务。
  • 当一个事务开始的时候,会指定一个回滚段,在事务进行的过程中,当数据被修改时,原始的数据会被复制到回滚段。
  • 在回滚段中,事务会不断填充盘区,直到事务结束或所有的空间被用完。如果当前的盘区不够用,事务会在段中请求扩展下一个盘区,如果所有已分配的盘区都被用完,事务会覆盖最初的盘区或者在回滚段允许的情况下扩展新的盘区来使用。
  • 回滚段存在于 undo 表空间中,在数据库中可以存在多个 undo 表空间,但同一时刻只能使用一个 undo 表空间。
  • 当事务提交时,InnoDB 引擎会做两件事
    • 将 undo log 放进特殊的列表中,后续供清除线程进行清除;
    • 判断所在的 undo 页是否可重用,若可以则分配给下一个事务使用。

03、回滚段中的数据分类

  • 未提交的回滚数据:该数据关联的事务还未提交,为了实现读一致性,该数据不能被其他事务覆盖。
  • 已提交但未过期的回滚数据:该数据关联的事务已经提交,但受到 undo retention 参数影响还未过期
  • 已提交且已过期的回滚数据:该数据关联的事务已提交且数据保存的时间已经超过 undo retention 的指定时间,属于过期数据。当回滚段满了之后,优先覆盖这部分数据。

事务提交后并不能马上删除 undo log 及 undo log 所在的页。这是因为可能还有其他事务需要通过 undo log 来得到行记录之前的版本。所以 事务提交时将 undo log 放入一个链表中,是否可以最终删除 undo log 及 undo log 所在页由清除线程来判断。

12.4 undo log 的类型

在 InnoDB 存储引擎中,undo log 分为两种类型:

  • insert undo log

    insert undo log 是指在 insert 操作中产生的 undo log。因为 insert 操作的记录只对事务本身可见,对其他事务不可见(这是事务隔离性的要求),所以该 undo log 可以在事务提交后直接删除。不需要进行清除线程操作。

  • update undo log

    update undo log 记录的是对 delete 和 update 操作产生的 undo log。该 undo log 可能需要提供 MVCC 机制,因此不能在事务提交时就进行删除。提交时放入 undo log 链表,等待清除线程进行最后的删除。

在 InnoDB 中为了更好的支持并发,InnoDB 的多版本一致性读是采用了基于回滚段的方式。另外,对于更新和删除操作,InnoDB并不是真正的删除原来的记录,而是设置记录的 delete mark 为 1。因此为了解决数据 Page 和 Undo Log 膨胀的问题,需要引入清除线程机制进行回收。

一般来讲我们理解的清除线程可以做如下的工作:

  • 清理 del flag 标签的记录
  • 清理 undo 的历史版本
  • 如果需要进行 undo tablespace 截断。

12.5 undo log 的生命周期

在这里插入图片描述
在更新 buffer pool 中的数据之前,需要先将该数据事务开始之前的状态写入到 undo log 中,假设更新到一般出错了,就可以通过 undo log 来回滚到事务开始前。

01、执行 insert 操作

begin;
insert into user(name) values("tom");

插入的数据都会生成一条 insert undo log,并且数据的回滚指针会指向它。undo log 会记录序号、插入主键的列和值等,在进行 rollback 的时候,通过主键直接把对应的数据删除即可。

在这里插入图片描述

02、执行 update 操作

begin;
update user set name = 'Sun' where id = 1;

会把老的记录写入新的 undo log,让回滚指针指向新的 undo log,它的 undo no 是 1,并且新的 undo log 会指向老的 undo log。
在这里插入图片描述
这时再执行:

update user set id = 2 where id = 1;

在这里插入图片描述
对于更新主键的操作,会把原来的数据 deletemark 表示打开,这时并没有真正的删除数据,真正的删除会交给清理线程去判断,然后在后面插入一条新的数据,新的数据也会产生 undo log,并且 undo log 的序号会递增。

每次对数据的变更都会产生一个 undo log,当一条记录被变更多次时,就会产生多条 undo log,undo log 记录的是变更前的日志 ,并且每隔 undo log 的序号是递增的,那么当要回滚的时候,按照序号依次向前推,就可以找到原始数据了。

undo log 是如何回滚的?就上面的例子来说,假设执行 rollback:

  1. 通过 undo no = 3 的日志把 id = 2 的数据删除;
  2. 通过 undo no = 2 的日志把 id = 1 的数据 deletemark 还原成 0;
  3. 通过 undo no = 1 的日志把 id = 1 的数据 name 还原成 Tom;
  4. 通过 undo no = 0 的日志把 id = 1 的数据删除。

03、执行 delete 操作

  • 对于 insert undo log

    因为 insert 操作的记录,只对事务本身可见,对其他事务不可见,所以该 undo log 可以在事务提交后直接删除,不需要进行清除线程操作。

  • 对于 update undo log

    该 undo log 可能需要提供 MVCC 机制 ,因此不能在提交事务时就进行删除。提交时放入 undo log 链表,等待清除线程进行最后的删除。

清除线程的两个主要作用:清理 undo 页和清除 page 里带有 delete_bit 标识的数据行。在 InnoDB 中,事务中的 delete 操作实际上并不是真正的删除掉数据行,而是一种 delete mark 操作,在记录上标识 delete_bit 而不删除记录 。只是一种 "假删除",做了个标记,真正的删除是由后台清除线程去完成的。

12.3 小结

在这里插入图片描述
undo log 是逻辑日志,对事务回滚时,只是将数据库逻辑地恢复到原来的样子。
redo log 是物理日志,记录的是数据页的物理变化,undo log 不是 redo log 的逆过程。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes部署练习

Kubernetes详细笔记 文章目录 Kubernetes 一、Kubernetes介绍 1.1、应用部署方式演变1.2、kubernetes简介1.3、kubernetes组件1.4、kubernetes概念 二、集群环境搭建 2.1、环境规划 2.1.1、集群类型2.1.2、安装方式2.1.3、主机规划 2.2、环境搭建 2.2.1、主机安装2.2.2、环境初…

如何开启华为交换机 http

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目…

【计算机网络 - 基础问题】每日 3 题(四十七)

✍个人博客:https://blog.csdn.net/Newin2020?typeblog 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞…

极速体验:实用的前端性能优化技巧

本文将深入探讨一系列实用的前端性能优化方案,从基础知识到高级技巧,我们将揭示如何让你的网站在瞬息万变的互联网中脱颖而出,无论你是经验丰富的开发者还是刚入行的新手,这篇文章都将为你提供宝贵的见解和实践建议。 目录 &…

python解决解析汉诺塔问题

👨‍💻个人主页:开发者-曼亿点 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 曼亿点 原创 👨‍💻 收录于专栏&#xff1a…

如何选择适合自己的IP地址切换器

在互联网活动中,IP地址切换器成为越来越多用户的必备工具。本文旨在帮助用户了解如何选择适合自己的IP地址切换器,以确保网络活动的顺利进行。 ​一、IP地址切换器的基本功能与优势 IP地址切换器,又称IP代理软件或IP更换器,是一种…

计算机通信与网络实验笔记

1.LINUX通过版本号判断是否为稳定版本 2.计网基础 (CD),默认二层以太网交换机。 (10)物理层是均分(除以),数据链路层及以上是不除的。 3.传输介质: (1&…

IDEA 中的代码调试指南

目录 前言1. 为什么进行代码调试1.1 找出错误1.2 优化代码1.3 提高对代码的理解 2. 如何在 IDEA 中进行代码调试2.1 设置断点2.1.1 普通断点2.1.2 条件断点 2.2 开始调试2.3 调试控制2.3.1 单步调试(Step Over)2.3.2 进入方法(Step Into&…

打印自然常数E

自然常数E 自然常数,符号e,为数学中一个常数,是一个无限不循环小数,且为超越数,其值约为2.718281828459045。它是自然对数函数的底数。 我们打印表达式(11/x)的x次方的值以及获取第一次大于2.718的正整数 新建C#控制…

今日指数项目集成SpringSecurity

项目集成SpringSecurity ​ 在第一章我们是基于SpringSecurity、JWT技术实现前后端无状态化认证授权,而我们当前的项目是前后端分离的架构,同样也可借助Security框架和Jwt实现前后端的无状态认证授权操作; 1、项目自定义认证过滤器 1.1 依…

DFF对比

第一种 单元1:电平触发触发器: 在CLK高电平时,输入D的变化才可以传递到输出Q;在CLK点评时,输出Q不变。 第一种的整体 将两个电平触发组合,得到单边沿触发 输出Q仅在CLK上升沿处发生变化。边沿触发 第二…

MySQL-27.多表查询-案例

一.数据准备 -- 分类表 create table category (id int unsigned primary key auto_increment comment 主键ID,name varchar(20) not null unique comment 分类名称,type tinyint unsigned not null comment 类型 1 菜品分类 2 套餐分类,sort …

Quartus Ⅱ仿真 1.半加器

真服了,csdn上一搜全是收费,服啦服啦,我就自己来写一个吧 仿真波形: 输出结果: 介绍: 半加器(Half Adder)是数字电路中的一种基本组件,用于实现两个一位二进制数的加…

AI 代写是变现最快的副业项目,没有之一

AI 时代可以做的副业项目很多,但是实事求是的讲,大部分副业变现周期都有点长,短则几个月,长则半年到一年。所以很多副业社群都强调要坚持,当一项副业你能坚持一个月,基本就熬走了 90% 的人。但是坚持这件事…

ubuntu 安装haproxy

####安装##### sudo apt update sudo apt install haproxy sudo haproxy -v sudo systemctl status haproxy sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg-org####配置站点##### nano /etc/haproxy/haproxy.cfgfrontend www-httpbind *:5001mode httpdefault_ba…

复旦大学全球供应链研究中心揭牌,合合信息共话大数据赋能

10月13日,复旦大学全球供应链研究中心(以下简称“中心”)揭牌仪式在复旦大学管理学院政立院区隆重举行。我国的供应链体系庞大复杂,在百年未有之大变局下,保障产业链供应链安全已成为我国的重要战略目标。中心的设立旨…

Netty无锁化设计之对象池实现

池化技术是比较常见的一种技术,在平时我们已经就接触很多了,比如线程池,数据库连接池等等。当我们要使用一个资源的时候从池中去获取,用完就放回池中以便其他线程可以使用,这样的目的就是为了减少资源开销,…

Python | Leetcode Python题解之第485题最大连续1的个数

题目: 题解: class Solution:def findMaxConsecutiveOnes(self, nums: List[int]) -> int:maxCount count 0for i, num in enumerate(nums):if num 1:count 1else:maxCount max(maxCount, count)count 0maxCount max(maxCount, count)return …

100 种下划线 / 覆盖层动画 | 终极 CSS(层叠样式表)集合

还在为你的菜单项和链接寻找动画效果而感到疲惫吗? 不用再找了!这里列出了 100 多种不同的动画。从简单的到更复杂的,你肯定能找到自己想要的。 无需 SVG(可缩放矢量图形),无需 JavaScript(脚…

八股面试2(自用)

mysql存储引擎 存储引擎:定义数据的存储方式,以及数据读取的实现逻辑 在以前数据库5.5默认MyISAM引擎,之后默认InnoDB引擎 MyISAM引擎的数据和索引是分开存储的,InnoDb将索引和文件存储在同一个文件。 MyISAM不支持事务&#…