当前位置: 首页 > news >正文

mysql系列8—Innodb的undolog

背景

本文涉及的内容较为底层,做了解即可,是以前学习《高性能mysql》和《mysql是怎样运行的》的笔记整理所得。

undolog设计的初始目的是保证事务的原子性。mysql的修改操作发生后,如果所在的事务未被提交,如mysql服务或者操作系统发送了异常或执行了回滚等情况,事务的已修改操作需被还原。而还原需记录必要的数据,这些数据就是undolog。针对插入、删除、修改操作,undolog需要记录的信息量不同:
[1] 新增: 需要把主键记录下来,回滚时,删除主键对应的记录;
[2] 删除: 保存整条记录,回滚时,重新插入记录;
[3] 修改: 保存修改前后的记录,回滚时使用旧值替换新值。
通过特定的设计,可以减少上述信息量的存储,以提高资源使用效率。如mysql实现删除操作时,会通过delete_mark标记已删除(中间状态),对应的undolog日志中就不需要存储完整的记录。

1.undo日志内容

不同操作类型的undolog存储的数据量不同,为减少undolog存储空间,mysql分别设计了对应的数据存储格式,本章将以Insert为例介绍。
有几个概念需要提前了解。
[1] undo ID: 每条Undo日志对应一个ID。
[2] table ID: 每个表都对应一个ID, 可通过innodb_tables查询表ID信息,如:

mysql> SELECT NAME, TABLE_ID, SPACE, ROW_FORMAT, SPACE_TYPE FROM information_schema.innodb_tables WHERE name='test/t_student';
+----------------+----------+-------+------------+------------+
| NAME           | TABLE_ID | SPACE | ROW_FORMAT | SPACE_TYPE |
+----------------+----------+-------+------------+------------+
| test/t_student |    16148 | 15086 | Redundant  | Single     |
+----------------+----------+-------+------------+------------+

此时表ID为16148.

[3] db_trx_id和db_roll_pointer
每条记录包含3个隐藏列,其中两个是db_trx_id和db_roll_pointer,分别表示事务ID和回滚指针。
db_trx_id(事务ID)表示当前记录被新增或者最后一次修改对应的事务ID。
其中,事务ID是一个不断递增的全局变量;事务只有发送修改时,才会被分配一个事务ID,每个事务的ID全局唯一。
db_roll_pointer(回滚指针)表示指向该条记录对应的undo日志(下文介绍)。

[4] next_record属性
在[mysql系列2—InnoDB数据存储方式]介绍过: mysql表的每条记录都有一个指向下一条记录的指针,记录之间通过next_record形成链表。

1.1 undo日志格式

undo日志格式格式如下图所示:
在这里插入图片描述
包含四个部分:
[1] 边界信息
end of record存储本条undo日志的结束位置;start of end存储本条undo日志的起始位置;二者用于确定该条undo日志的边界。

[2] undo type
undo type记录了当前undo日志的类型信息; 不同的类型确定了不同的日志内容存储格式。

[3] undo ID和table ID
undo ID 表示该Undo的全局唯一ID,table ID表示修改操作涉及的表的ID。

[4] 日志信息
存储undo日志信息的数据部分,mysql根据undo type确定日志格式和对应的解析逻辑。Insert、Update、Delete操作在这部分存储格式有所区别。

1.2 insert操作

mysql记录Insert类型的Undo日志,只需要保存主键信息即可,如下图所示:
在这里插入图片描述
undo日志部分中存放了主键的各列的长度和实际的数值。
以下结合案例进行说明。
创建一个t_student表:

CREATE TABLE `t_student` (`id` INT(10) NOT NULL COMMENT '学号,唯一ID',`name` VARCHAR(50) NOT NULL COMMENT '姓名',`country` VARCHAR(32) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `unix_name` (`name`) USING BTREE
)
ENGINE=InnoDB
;

包含一个主键索引和一个唯一索引;
开启一个事务(事务ID为100),向t_student其中插入两条数据:

start transaction;INSERT INTO `t_student` (`id`, `name`, `country`) VALUES (1, 'sy', '中国');
INSERT INTO `t_student` (`id`, `name`, `country`) VALUES (2, 'mf', '澳大利亚');

从information_schema.innodb_tables表中查询得到t_student的table ID为16148.
此时数据记录和undo日志如下所示:
在这里插入图片描述
两个插入操作对应的类型为trx_undo_insert_rec;undo no存放的是undo日志ID, 分别为100和101;table ID存储的是t_student的table ID为16148; 数据部分存储主键大小和实际的值,整形长度为4;主键数值分别为1和2.
为了下文表述方便,对上图的日志细节部分进行忽略,简化表示为:
在这里插入图片描述
图中插入的两条记录通过next_record形成了记录链;每条记录的db_roll_pointer指向了记录对应的Undo日志。
其中:id=1的undo日志ID为100(后续用undolog100表示);id=2的undo日志ID为101(后续用undolog101表示).

1.3 delete操作和update操作

insert和delete对每行记录的操作只会对应产生一条UNDO日志;update语句修改某条记录的主键时产生两条日志,否则产生一条日志。

delete和update操作对应的undo行为是恢复数据,因此需要在日志内容区域存储除主键外更多的信息,其中包括原记录对应的事务ID和Undo指针。以下结合案例进行说明。
当事务100执行插入操作后,继续执行update操作时:

UPDATE t_student SET country = '上海' WHERE id = 2;

在这里插入图片描述
update操作修改了主键为2的记录,对应的undo日志ID为102(后续用undolog102表示). undolog102中存在一个old_roll_pointer指针,指向了undolog101.
当事务100执行update操作后,继续执行delete操作时:

delete from t_student WHERE id = 2;

在这里插入图片描述
delete操作删除了主键为2的记录,减delete_mark标记为1表示该记录已被删除;对应的undo日志ID为103(后续用undolog103表示). undolog103中存在一个old_roll_pointer指针,指向了undolog102.
说明:也可以提交事务100后(不提交会因行锁冲突阻塞更新),再开启一个事务执行更新或者删除操作,效果与案例相似(仅保存的旧事务ID不别)。

1.4 版本链

insert语句在事务提交后UNDO日志会被删除;而delete和update类型的UNDO日志会参与MVCC,即使所在事务提交,也不会立即删除(而是后续有单独的线程完成清理)。

上一节中id为2的记录对应的undolog通过roll_ptr指针相连,将其单独抽出来得到一个链表,叫做版本链。
在这里插入图片描述

2.undo页

前面已经介绍了undo日志格式,undo日志会按照格式存放到FIL_PAGE_UNDO_LOG (undo页)中,undo页的结构如下所示:
在这里插入图片描述
File Header和File Trailer是页的固定格式,在介绍数据页时已经介绍过,这里关注一下Undo Page Header, 包括如下4个部分:
[1] type: Undo日志大类,Insert类型和其他类型(delete和update类型);
[2] page_start: 第一条undo日志的起始位置;
[3] page_free: 下一条undo日志的可写入位置;
[4] node信息: 存储链表信息,在下一章中介绍。

3.undo链表

一个事务可能有多个操作命令,每个操作命令可能修改多个行;即一个事务在执行过程中可能生成多个Undo日志,因此一个undo页可能写不完,所以mysql引入了一个undo链的概念。
在这里插入图片描述
上一章节中node存储的就是串联undo页之间的指针信息,undo页通过node信息形成双向链表。
mysql整体上将Undo日志分为了两类: insert类型和其他类型(update和delete)。Insert类型的Undo日志在事务提交后可以直接删除;而其他类型的undo日志参与MVCC,不能直接删除,而是由后续专门的线程负责清理。因此,为了提高效率,mysql将不同类型的日志存放到在不同的undo页中。
说明:并不是事务创建时就分配undo链,而是按需分配,发送数据修改时才会分配。
每个事务可能有多条链:
在这里插入图片描述
除此之外,对于临时表,还有单独的两个链表(原理相同,本文不做介绍)。
最后,为了提高undo日志写入效率,不同的事务在执行过程中生成的undo日志存放到不同的undo页面链表中;即每个事务有自己单独的undo链表。

相关文章:

mysql系列8—Innodb的undolog

背景 本文涉及的内容较为底层,做了解即可,是以前学习《高性能mysql》和《mysql是怎样运行的》的笔记整理所得。 undolog设计的初始目的是保证事务的原子性。mysql的修改操作发生后,如果所在的事务未被提交,如mysql服务或者操作系统…...

静默安装OGG for MySQL微服务版本,高效开展数据同步和迁移

一、背景 本文从Oracle GoldenGate微服务版的概念和组件介绍开始,从零介绍了怎么开始安装GoldenGate 21c for Oracle微服务版本的软件及部署。当然了,微服务版除新功能外包含传统版所有的功能。 二、安装部署 (一)下载OGG for …...

【Golang 面试题】每日 3 题(五十五)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...

PHP关键字入门指南:分类与功能全解析

如果你是刚接触PHP的新手,可能会对代码中那些“特殊单词”感到困惑。别担心!本文将用最通俗易懂的方式,带你认识PHP中的关键字——它们就像编程世界的“魔法咒语”,每个都有独特的作用。文末还附有代码示例,帮你快速上手! 一、什么是PHP关键字? PHP关键字是语言内置的特…...

消息中间件深度剖析:以 RabbitMQ 和 Kafka 为核心

在现代分布式系统和微服务架构的构建中,消息中间件作为一个不可或缺的组件,承担着系统间解耦、异步处理、流量削峰、数据传输等重要职能。尤其是在面临大规模并发、高可用性和可扩展性需求时,如何选择合适的消息中间件成为了开发者和架构师们…...

【万字详细教程】Linux to go——装在移动硬盘里的Linux系统(Ubuntu22.04)制作流程;一口气解决系统安装引导文件迁移显卡驱动安装等问题

Linux to go制作流程 0.写在前面 关于教程Why Linux to go?实际效果 1.准备工具2.制作步骤 下载系统镜像硬盘分区准备启动U盘安装系统重启完成驱动安装将系统启动引导程序迁移到移动硬盘上 3.可能出现的问题 3.1.U盘引导系统安装时出现崩溃3.2.不影响硬盘里本身已有…...

HCIA项目实践---OSPF的基本配置

9.5.12 OSPF的基本配置 (所搭环境如上图所示) A 先配置IP地址 (先进入路由器R1的0/0/0接口配置IP地址,再进入环回接口配置IP地址) (配置R2路由器的0/0/0和0/0/1以及环回接口的IP地址) (置R3路由器的0/0/0接…...

Vue 自动配置表单 el-switch等不常用组件覆盖默认值问题

有自动解析表单的vue组件如下&#xff0c;其原理是调用一个配置表单定义的接口&#xff0c;然后再调用获取表单配置的接口并将配置的数据覆盖表单的默认值。其中el-switch的配置值没有覆盖默认值&#xff0c;分析其原因。 主页面如下&#xff1a; <template> <div cla…...

零基础购买阿里云服务器,XShell连接云服务器

目录 1.环境搭建方式 2. 使用云服务器 3.使用终端软件登录到Linux 4.使用XShell登录主机 5.连接失败的原因&#xff1a; 下一篇更新&#xff1a;Linux的基础指令以及如何Linux的环境搭建 1.环境搭建方式 主要有四种: 1.直接安装在物理机上&#xff0c;虽然Linux有图形化…...

【系统架构设计师】虚拟机体系结构风格

目录 1. 说明2. 解释器体系结构风格3. 规则系统体系结构风格4. 例题4.1 例题1 1. 说明 1.p263。2.虚拟机体系结构风格的基本思想是人为构建一个运行环境&#xff0c;在这个环境之上&#xff0c;可以解析与运行自定义的一些语言&#xff0c;这样来增加架构的灵活性。3.虚拟机体…...

C语言中qsort函数使用技巧

在C语言的标准库中&#xff0c; qsort 函数是一个强大的通用排序函数&#xff0c;它采用快速排序算法&#xff0c;能够高效地对各种数据类型的数组进行排序。掌握 qsort 函数的使用技巧&#xff0c;对于提升程序的效率和代码的简洁性至关重要。 一、qsort函数基本介绍 qsort 函…...

WPF的Prism框架的使用

安装Prism.DryIoc库&#xff1a; Prism的区域和模块化&#xff1a; 一个区域可以显示一个用户控件 一个模块就是一个项目&#xff0c;也就是一个类库 动态切换用户控件的案例&#xff1a; <Grid><Grid.RowDefinitions><RowDefinition Height"auto"…...

LeetCode每日精进:142.环形链表II

题目链接&#xff1a;142.环形链表II 题目描述&#xff1a; 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环…...

CPP集群聊天服务器开发实践(五):nginx负载均衡配置

1 负载均衡器的原理与功能 单台Chatserver可以容纳大约两万台客户端同时在线聊天&#xff0c;为了提升并发量最直观的办法需要水平扩展服务器的数量&#xff0c;三台服务器可以容纳六万左右的客户端。 负载均衡器的作用&#xff1a; 把client的请求按照负载均衡算法分发到具体…...

easyexcel解析excel文件的时候报错

easyexcel解析xls文件的时候&#xff0c;报错Exception in thread "main" com.alibaba.excel.exception.ExcelAnalysisException: java.lang.NoClassDefFoundError: org/objectweb/asm/Type at com.alibaba.excel.analysis.ExcelAnalyserImpl.analysis(ExcelAnalyser…...

Android设备 网络安全检测

八、网络与安全机制 6.1 网络框架对比 volley&#xff1a; 功能 基于HttpUrlConnection;封装了UIL图片加载框架&#xff0c;支持图片加载;网络请求的排序、优先级处理缓存;多级别取消请求;Activity和生命周期的联动&#xff08;Activity结束生命周期同时取消所有网络请求 …...

word分栏使得最后一页内容自动平衡

word分栏使得最后一页内容自动平衡 Word中的分页符分节符 Word中的分页符与分节符统称为分隔符 【分页符】 是将一页内容分成两页, 但分离后的两页属于同一节;分页符用于强制在当前位置分页, 后续内容从下一页开始;分页符对应快捷键 Ctrl Enter ; 【分节符】 分节符用…...

完全免费稳定WebTerm网页版在线SSH连接,在线远程连接云服务器,可以控制背景,支持SFTP访问服务器文件。无需安装即可在线连接和管理服务器的SSH终端工具。支持跨平台设备。

目录 用途介绍 网页版SSH使用说明及教程 首次登录配置 设置中心介绍 ​编辑 SFTP功能 用途介绍 各位开发者在使用远程服务器时经常面临一个很致命的问题&#xff0c;就是当没有在使用自己电脑&#xff0c;远程服务器商家又没有提供在线的VNC连接&#xff0c;这时重新去安装…...

微信小程序医院挂号系统

第3章 系统设计 3.1系统体系结构 系统的体系结构非常重要&#xff0c;往往决定了系统的质量和生命周期。针对不同的系统可以采用不同的系统体系结构。本系统为微信小程序医院挂号系统&#xff0c;属于开放式的平台&#xff0c;所以在管理端体系结构中采用B/s。B/s结构抛弃了固…...

编程题-最大子数组和(中等-重点【贪心、动态规划、分治思想的应用】)

题目&#xff1a; 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 解法一&#xff08;枚举法-时间复杂度超限&#xff09;&#xff1a; …...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

算法打卡第18天

从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7…...

大数据治理的常见方式

大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法&#xff0c;以下是几种常见的治理方式&#xff1a; 1. 数据质量管理 核心方法&#xff1a; 数据校验&#xff1a;建立数据校验规则&#xff08;格式、范围、一致性等&#xff09;数据清洗&…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...