undolog

一、原子性

ACID:通过undolog保证原子性

二、undolog 如何做

把回滚时所需的东西都给记下来:
1、插入一条记录时,至少要把这条记录的主键值记下来,回滚的时候只需要把这个主键值对应的记录删掉就好了。 
2、删除了一条记录,至少要把这条记录中的内容都记下来,回滚时再把由这些内容组成的记录插入 到表中就好了。 
2、修改了一条记录,至少要把修改这条记录前的旧值都记录下来,回滚时再把这条记录更新为旧值 就好了。

三、事务id

3.1 分配事务id时机

        某个事务执行过程中对某个表执行了增、删、改操作,那么 InnoDB 存储引擎就会给它分配一个独一无二的 事务id,如果只有读请求则不会分配事务id

3.2 事务id如何生成

1、服务器会在内存中维护一个全局变量,每当需要为某个事务分配一个 事务id 时,就会把该变量的值当作 事 务id 分配给该事务,并且把该变量自增1。
2、每当这个变量的值为 256 的倍数时,就会将该变量的值刷新到系统表空间的页号为 5 的页面中一个称之为 Max Trx ID 的属性处,这个属性占用 8 个字节的存储空间。
3、当系统下一次重新启动时,将上边提到的 Max Trx ID 属性加载到内存,该值加上256之后赋值给我们 前边提到的全局变量(因为在上次关机时该全局变量的值可能大于 Max Trx ID 属性值)。
***保证整个系统中分配的事务id是一个递增的数字。先被分配 id 的事务得到的是较小的事务id , 后被分配 id 的事务得到的是较大的 事务id 。***

3.3 trx_id隐藏列

trx_id 列其实还蛮好理解的,就是某个对这个聚簇索引记录做改动的语句所在的事务对应的 事务id 而已 (此处的改动可以是 INSERT 、 DELETE 、 UPDATE 操作)。

四、undo日志的格式 

4.1 insert对应的undolog

4.1.1 undolog日志结构

插入一条记录时有 乐观插入悲观插入 区分,对应TRX_UNDO_INSERT_REC 类型的undolog

 4.2.2 undolog记录实例

1、执行两个insert语句:

INSERT INTO undo_demo(id, key1, col) VALUES (1, 'AWM', '狙击枪'), (2, 'M416', '步枪');

2、第一条 undo日志 的 undo no 为 0 ,记录主键占用的存储空间长度为 4 ,真实值为 1 。画一个示意图就是 这样:

3、第二条undo日志 的 undo no 为 1 ,记录主键占用的存储空间长度为 4 ,真实值为 2 。画一个示意图就是 这样(与第一条 undo日志 对比, undo no 和主键各列信息有不同): 

4.2 DELETE对应的undo log

4.2.1 删除操作数据结构

Page Header 部分有一个称之为 PAGE_FREE 的属性,被删除的记录其实也会根据记录头信息中的 next_record 属性组成一个链表,只不过这个链表中的记录占用的存储空间可以被重新利用,所以也称这个链表 为 垃圾链表。

4.2.2 删除操作2个阶段 

1、阶段一:delete mark:仅仅将记录的 delete_mask 标识位设置为 1 ,其他的不做修改(其实会修改记录的 trx_id 、 roll_pointer 这些隐藏列的值),是一个 中间状态。

2、阶段二:purge 删除语句事务提交,有专门的线程后来真正的把记录删除掉。就 是把该记录从 正常记录链表 中移除,并且加入到 垃圾链表 中,还要调整一些页面的其他信息,比如页 面中的用户记录数量 PAGE_N_RECS 、上次插入记录的位置 PAGE_LAST_INSERT 、垃圾链表头节点的指针 PAGE_FREE 、页面中可重用的字节数量 PAGE_GARBAGE 、还有页目录的一些信息。

3、阶段二执行完成

将被删除记录加入到 垃圾链表 时,实际上加入到链表的头节点处,会跟着修改 PAGE_FREE 值。

4.2.3 删除操作日志结构

对应TRX_UNDO_DEL_MARK_REC类型的undolog,结构如下:

4.2.4 版本链

在对一条记录进行 delete mark 操作前,需要把该记录的旧的 trx_id 和 roll_pointer 隐藏列的值都给记 到对应的 undo日志 中来,对应图中的 old trx_id 和 old roll_pointer 属性。可以通过 undo日志 的 old roll_pointer 找到记录在修改之前对应的 undo 日志。比方说在一个事务 中,我们先插入了一条记录,然后又执行对该记录的删除操作,这个过程的示意图就是这样:

从图中可以看出来,执行完 delete mark 操作后,它对应的 undo log和 INSERT 操作对应的 undo 日志就串 成了一个链表。这个链表就称之为 版本链。

4.2.5 删除实例

BEGIN; # 显式开启一个事务,假设该事务的id为100
# 插入两条记录
INSERT INTO undo_demo(id, key1, col)
 VALUES (1, 'AWM', '狙击枪'), (2, 'M416', '步枪');
# 删除一条记录
DELETE FROM undo_demo WHERE id = 1;

这个 delete mark 操作对应的 undo日志 的结构就是这样: 


1、这条 undo 日志是 id 为 100 的事务中产生的第3条 undo 日志,所以它对应的 undo no 是 2 。 
2、在对记录做 delete mark 操作时,记录的 trx_id 隐藏列的值是 100 (也就是说对该记录最近的一次修改就 发生在本事务中),所以把 100 填入 old trx_id 属性中。然后把记录的 roll_pointer 隐藏列的值取出 来,填入 old roll_pointer 属性中,这样就可以通过 old roll_pointer 属性值找到最近一次对该记录做改 动时产生的 undo日志 。 
3、由于 undo_demo 表中有2个索引:一个是聚簇索引,一个是二级索引 idx_key1 。只要是包含在索引中的列,那么这个列在记录中的位置( pos ),占用存储空间大小( len )和实际值( value )就需要存储到 undo日志 中。 
    对于主键来说,只包含一个 id 列,存储到 undo日志 中的相关信息分别是:
    pos:id 列是主键,在记录的第一个列,它对应的 pos 值为 0 。 pos 占用1个字节来存储。 
    len : id 列的类型为 INT ,占用4个字节,所以 len 的值为 4 。 len 占用1个字节来存储。 
    value :在被删除的记录中 id 列的值为 1 ,也就是 value 的值为 1 。 value占用4个字节来存储。 画一个图演示一下就是这样:

 

对于 id 列来说,最终存储的结果是 ,存储这些信息占用的存储空间大小为 1 + 1 + 4 = 6 个字节。
对于 idx_key1 来说,只包含一个 key1 列,存储到 undo日志 中的相关信息分别是: 
    pos : key1 列是排在 id 列、 trx_id 列、 roll_pointer 列之后的,它对应的 pos 值为 3 。 pos 占用1个字节来存储。 
    len : key1 列的类型为 VARCHAR(100) ,使用 utf8 字符集,被删除的记录实际存储的内容是 AWM ,所以一共占用3个字节,也就是所以 len 的值为 3 。 len 占用1个字节来存储。 
    value :在被删除的记录中 key1 列的值为 AWM ,也就是 value 的值为 AWM 。 value 占用3个字节 来存储。

 key1 列来说,最终存储的结果是 ,存储这些信息占用的存储空间大小 为 1 + 1 + 3 = 5 个字节。

<0, 4, 1> 和 <3, 3, 'AWM'> 和 共占用 11 个字节。然后 index_col_info len 本身占用 2 个字节,所以加起来一共占用 13 个字节,把数字 13 就填到了 index_col_info len 的 属性中。

4.2 roll pointer隐藏列的含义

占用 7 个字节的字段,本质上就是一个指向记录对应的 undo日志的指针 。

数据记录被存储到了类型为 FIL_PAGE_INDEX 的页面中(就是我们前边一直所说的 数据页 ), undo日志 被存放到了类型为 FIL_PAGE_UNDO_LOG 的页面中。

 

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

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

相关文章

基于Vue前端框架构建BI应用程序

一、什么是Vue&#xff1f; Vue&#xff08;Vue.js&#xff09;是一个轻量级、高性能、可组件化的MVVM库。简而言之&#xff0c;是一个构建数据驱动的web界面的渐进式框架。它采用MVVM思想&#xff0c;通过数据双向绑定实现数据的动态渲染&#xff0c;同时也支持组件化的开发方…

IO模型和NGINX安装升级

IO模型和NGINX安装升级 IO模型 IO概念 I/O在计算机中指Input/Output&#xff0c; IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数)&#xff0c;是衡量磁盘性能的主要指标之一。 Linux的IO类型 磁盘I/O 磁盘I/O是进程向内核发起系统调用&#xff0c;请求磁…

ceph中PGLog处理流程

ceph的PGLog是由PG来维护&#xff0c;记录了该PG的所有操作&#xff0c;其作用类似于数据库里的undo log。PGLog通常只保存近千条的操作记录(默认是3000条&#xff0c; 由osd_min_pg_log_entries指定)&#xff0c;但是当PG处于降级状态时&#xff0c;就会保存更多的日志&#x…

sql各种注入案例

目录 1.报错注入七大常用函数 1)ST_LatFromGeoHash (mysql>5.7.x) 2)ST_LongFromGeoHash &#xff08;mysql>5.7.x&#xff09; 3)GTID (MySQL > 5.6.X - 显错<200) 3.1 GTID 3.2 函数详解 3.3 注入过程( payload ) 4)ST_Pointfromgeohash (mysql>5.…

gitee上传本地项目bug

&#x1f92e;这个破bug不知道浪费了多长时间&#xff0c;以前没有记录&#xff0c;每次都忘记&#xff0c;这次记下来 问题描述 gitee创建仓库&#xff0c;然后根据它提示的如下命令&#xff0c;但一直报错 原因分析&#xff1a; 把命令复制出来&#xff0c;粘贴到Sublime …

【C++进阶】模板进阶

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

tableau基础学习2:时间序列数据预处理与绘图

文章目录 数据预处理1. 原始数据2. 合并数据集2. 创建计算字段 绘图分析1. 趋势分析2. 计算字段趋势分析 这一部分&#xff0c;我们记录一些分析时序趋势的分析步骤 数据预处理 1. 原始数据 原始数据是excel表格&#xff0c;其中包含三个Sheet页&#xff0c; 这里我们选择两…

青翼科技基于VITA57.1的16路数据收发处理平台产品手册

FMC211是一款基于VITA57.1标准规范的实现16路LVDS数据采集、1路光纤数据收发处理FMC子卡模块。 该板卡支持2路CVBS&#xff08;复合视频&#xff09;视频输入&#xff0c;能够自动检测标准的模拟基带电视信号&#xff0c;并将其转变为8位ITU-R.656接口信号或者4:2:2分量视频信…

日本橙皮书数据库—《医疗用医药品质量情报集》

日本橙皮书是一份关于医疗用医药品质量情报的汇总报告&#xff0c;由日本厚生劳动省发布。它主要涵盖了药品的品质再评价信息&#xff0c;特别是针对特定历史阶段的产品&#xff0c;笔者总结信息如下&#xff1a; ①日本橙皮书数据库包含了一系列药品的详细信息&#xff0c;如…

【Go 基础篇】Go语言中的数组:初识与应用

Go语言以其简洁、高效和强大的特性在编程界广受欢迎。数组作为一种基本的数据结构&#xff0c;在各种应用场景中扮演着重要角色。本文将引入Go语言中的数组&#xff0c;介绍其特点、创建、初始化以及基本应用&#xff0c;为你打开数组的大门。 前言 数组是一种固定大小的数据…

「网页开发|前端开发|Vue」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转

本文主要介绍如何使用路由控制来实现将一个单页面网站扩展成多页面网站&#xff0c;包括页面扩展的逻辑&#xff0c;vue的官方路由vue-router的基本用法以及扩展用法 文章目录 本系列前文传送门一、场景说明二、基本的页面扩展页面扩展是在扩什么创建新页面的代码&#xff0c;…

Omni Recover for Mac(专业的iPhone数据恢复软件)

Omni Recover for Mac是一款专业的Mac数据恢复软件&#xff0c;能够帮助用户快速找回被误删除、格式化、病毒攻击等原因造成的文件和数据&#xff0c;包括图片、视频、音频、文档、邮件、应用程序等。同时&#xff0c;Omni Recover for Mac还具有数据备份和清理功能&#xff0c…