不重用的undo日志 (2)—mysql进阶(六十五)

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
RDS AI 助手,专业版
简介: 不重用的undo日志 (2)—mysql进阶(六十五)

前面我们说了undo日志在insert,update,delete存储的日志格式,delete存储的type是trx_undo_del_mark_rec里面有个参数old roll_pointer会指向insert的地址值,恢复需要的数据。Select是没有undo日志的,因为select不需要回滚事务。

undo日志insert,update,delete (1)—mysql进阶(六十四)


通用链表结构


在写入undo日志的过程会使用到多个链表,很多链表都有同样的节点结构,

List node结构示意图(一共12个字节):

Prev Node page number(4个字节):

Prev node offset(2个字节):这两个字段相当于指向前一个节点的指针。

Next node page number(4个字节):

Next node offset(2个字节):这两个字段相当于指向后一个节点的指针。

在某个表空间内,我们可以通过一个页的页号和在页内的偏移量来唯一定位一个节点的位置,这两个信息也就是相当于指向这个节点的指。所以:

Prev node page number和prev node offset就是指向前一个节点的指针。

Next node page number 和next node offset就是指向后一个节点的指针。

整个list node占用12个字节的存储空间。

为了更好管理链表,设计innoDB的大叔还提出一个基节点的结构, 里面存储着这个链表的头节点、尾节点以及链表长度信息,基节点的结构示意图:

List base node 结构示意图(一共16个字节):

List length:(4个字节)

First node page number:(4个字节)

First node offset:(2个字节)这两个字段指向链接头节点的指针。

Last node page number:(4个字节)

Last node offset:(2个字节)这两个字段指向链接尾节点的指针。

其中list lenth代表有多少个节点。

而list base node结构有一个start和end,这个就是指向list node这个结构的start节点和end节点。


File_page_undo_log页面


前面唠嗑表空间的时候,其实有许许多多的页面构成,其中默认大小为16kb。比如fil_page_index的页面用于存储聚簇索引和二级索引,类型为fil_page_type_fsp_hdr的页面用于存储表空间头部信息,还有其他各种类型的页面,其中有一种是file_page_undo_log类型的页面专门用来存储undo日志的,默认16kb,他的结构如下:

File header:38个字节。

Undo page header:18个字节。

File body:这里都是真实存放undo日志的地方。

File trailder:8个字节。

File header 和file trailder都类似,就不介绍了,里面大致有lsn值,用于效验文件是否完整,header有组成双向链表的字段,prev和next等。

这里介绍一下undo page header:

TRX_UNDO_PAGE_TYPE:2个字节,本页面准备存储什么种类的undo日志。

我们介绍了好几种undo日志,大致分为两大类:

Trx_undo_insert(使用十进制1表示):类型是trx_undo_insert_rec的undo日志属于这个类,  一般insert语句产生,其中update语句更新主键的时候也会产生。

Trx_undo_update(使用十进制2表示):除了trx_undo_insert_rec的undo日志外,其他undo日志都属于此类,一般是update 和 delete产生的。

所以如果存储着trx_undo_insert的类,就只能存放trx_undo_insert_rec的undo日志。为什么要分为两大类呢,因为trx_undo_insert_rec可以直接删除,而其他类型的删除是delete mark,还需要为其他事物服务,这就是MVCC,后面会详细介绍。

Trx_undo_page_start:表示在当前页面从什么位置开始存储undo日志的,或者说表示第一条undo日志在页面中起始偏移量。

Trx_undo_page_free:与上面的start对应,存入最后一个undo日志的偏移量,可以继续存入undo日志的地址值。(当然,在最初一条undo日志未写入的时候,两个字段是相同的)

Trx_undo_page_node:代表一个list node结构(链表的普通节点)。


UNDO页面链表


单个事务中的undo页面链表

一个事务可能包含多个sql语句,而一个sql语句可能对多条记录进行改动,而每条记录的改动,都可能会记录1条或者2条undo日志,所以在一个事务里会产生很多undo日志,可能一个页面放不下需要放入多个页面,通过TRX_undo_page_node属性连接成了链表

我们吧undo页面第一个称为first undo page,其余的undo页面称为normal undo page,这是因为first undo page 中除了记录undo page header外,还会记录一些管理信息。

在一个事务中,可能混着执行insert update delete,意味着产生不同的undo日志,但我们前面说过,同一个undo要么存在trx_undo_insert或者存在trx_undo_update,反正不能混着存,所以一个事务里就需要两个undo链表,一个称为insert undo链表,另一个称为update undo链表。

另外有规定,普通表和临时表的链表要分开存储,所以就有了四个链表。

当然不是事务开启的时候就分配这四个链表,当对普通表或者临时表操作的时候,才会分配相对应的链表。总之按需分配,啥时候执行了update 或者 insert,delete就分配,如果没有执行,就不分配。


多个事务中的undo页面链表


为了提高undo日志分配效率,可以不同事务同事运行,不同事务运行的情况下,会给不同的事务分配不同的链表。

列子:

Trx1:运行了update了普通表,insert了临时表

则会有在trx1里分配临时表的trx_undo_insert链表和普通表的trx_undo_update链表。

Trx2:运行了insert普通表

则会有在trx里分配普通表的trx_undo_insert链表

如果有更多的事务,意味着有更多的链表。


Undo日志具体写入过程


段(segment)的概念


前面段的概念介绍过,一个索引会有内节点和叶子节点,所以有两个段,段是由零散的页和完整的区组成。每个段都对应inode entry结构,这个inode entry里面有各种信息,比如段的id,段内各种链表基节点,零散页面有哪些信号等,我们前面说了inode entry有一个segment header:

他的大小是10个字节,

Space id of the inode entry:所在的表空间id。

Page number of the inode entry:inode entry 结构所在的页面页号

Byte offset of the inode entry:inode entry结构在页面中的偏移量。

知道了表空间,页号以及偏移量,就可以找到他对应的inode entry地址了。


Undo log segment header


innoDB规定每undo页面都对应一个段,称为undo log segment。也就是链表里的页面都是从这个段里申请的,也就是first undo page中设计了一个称为undo log segment header 的部分:

file heard:38个字节。

Undo page header:18个字节。

Undo log segment header:30个字节。

Body:存放真正的undo日志及其其他东西。

File trailer:8个字节。

可以看到这个undo链表比其他普通页面多了undo log segment header:

Trx_undo_state:本undo页面链表处在的状态。

一个undo log segment处在的状态包括:

Trx_undo_active:活跃状态,也就是一个活跃的事务也在往这个段里写undo日志。

Trx_undo_cache:被缓存的状态。处在该状态的undo页面链表等待着之后被其他事务重用。

Trx_undo_to_free:对于insert undo链表来说,如果他对应的事务提交后,该链表不能被重用,那么久处于这种状态。

Trx_undo_prepared:包含处在prepare阶段的事务产生的undo日志。

注意:prepared阶段是在分布式事务中才出现的。

Trx_undo_last_log:本undo页面链表中最后一个undo log header 位置。

Trx_undo_fseg_header:本undo页面链表对应的段segment_header信息(就是前面说的10个字节的结构,可以找到对应的inode entry)。

Trx_undo_page_list:undo页面链表的基节点。

我们前面说了undo页面的undo page header部分有一个12字节大小的trx_undo_page_node的属性,这个代表list node结构。每一个undo页面都包含undo page header 结构,可以连接成一个链表。Trx_undo_page_list就是基节点,当然这个只存在第一个页面,first undo page。


Undo log header


事务往undo页面写入undo日志是直接往里面怼,各个日志亲密无间。写完一个undo页面后,再从段里申请新的页面,然后把这个页面插入undo页面链表中,继续往这个新申请的页面中写。innoDB认为同一个事务向一个链表插入的undo日志为一组,比如trx1事务里有两组,trx2事务里有三组。在每组写入undo日志时,都会记录一些这个组的属性,存储这些属性的地方称为undo log header。所以在真正写入undo日志之前,其实需要填充undo page header、undo log segment header,undo log header。


它的具体结构:

Trx_undo_trx_id:生成本组的undo日志事务id。

Trx_undo_trx_no:事务提交后生成一个需要的序号,使用此序号来标记事务提交顺序。(先提交小的后提交大的)

Trx_undo_del_marks:标记本组undo日志中是否包含delete mark操作的undo日志。

Tra_undo_log_start:本组undo日志中第一条undo日志在页面中的偏移量。

Trx_undo_xid_exists:本组undo日志是否包含xid。

Trx_undo_dict_trans:标记本组undo日志是不是由DDL语句产生的。

Trx_undo_table_id:如果trx_undo_dict_trans为真,那么本属性表示DDL语句操作的表table id。

Trx_undo_next_log:下一组undo日志在页面的偏移量。

Trx_undo_prev_log:上一组undo日志在页面的偏移量。

Trx_undo_history_node:一个12个字节的list node 结构,代表一个称为history链表的节点。


综上,对于没有重用的undo链表来说,也就是第一个first undo page在真正写入undo日志之前,会填充undo page header、undo log segment header,undo log header这三个部分才开始正式写入undo日志。对于剩余的其他normal_undo_page来说,真正写入之前,会先填充undo page header。链表的list base node存在first undo page的undo log segment header部分,list node会存放在每一个undo页面的undo page header部分。


相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
9月前
|
SQL 运维 关系型数据库
深入探讨MySQL的二进制日志(binlog)选项
总结而言,对MySQL binlogs深度理解并妥善配置对数据库运维管理至关重要;它不仅关系到系统性能优化也是实现高可靠性架构设计必须考虑因素之一。通过精心规划与周密部署可以使得该机能充分发挥作用而避免潜在风险带来影响。
275 6
|
SQL 监控 关系型数据库
MySQL日志分析:binlog、redolog、undolog三大日志的深度探讨。
数据库管理其实和写小说一样,需要规划,需要修订,也需要有能力回滚。理解这些日志的作用与优化,就像把握写作工具的使用与运用,为我们的数据库保驾护航。
860 23
|
SQL 运维 关系型数据库
MySQL Binlog 日志查看方法及查看内容解析
本文介绍了 MySQL 的 Binlog(二进制日志)功能及其使用方法。Binlog 记录了数据库的所有数据变更操作,如 INSERT、UPDATE 和 DELETE,对数据恢复、主从复制和审计至关重要。文章详细说明了如何开启 Binlog 功能、查看当前日志文件及内容,并解析了常见的事件类型,包括 Format_desc、Query、Table_map、Write_rows、Update_rows 和 Delete_rows 等,帮助用户掌握数据库变化历史,提升维护和排障能力。
|
SQL 存储 关系型数据库
简单聊聊MySQL的三大日志(Redo Log、Binlog和Undo Log)各有什么区别
在MySQL数据库管理中,理解Redo Log(重做日志)、Binlog(二进制日志)和Undo Log(回滚日志)至关重要。Redo Log确保数据持久性和崩溃恢复;Binlog用于主从复制和数据恢复,记录逻辑操作;Undo Log支持事务的原子性和隔离性,实现回滚与MVCC。三者协同工作,保障事务ACID特性。文章还详细解析了日志写入流程及可能的异常情况,帮助深入理解数据库日志机制。
1890 0
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
4975 32
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
601 9
|
监控 容灾 算法
阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
本文探讨了如何高效、经济且可靠地将海外应用与基础设施日志统一采集至阿里云日志服务(SLS),解决全球化业务扩展中的关键挑战。重点介绍了高性能日志采集Agent(iLogtail/LoongCollector)在海外场景的应用,推荐使用LoongCollector以获得更优的稳定性和网络容错能力。同时分析了多种网络接入方案,包括公网直连、全球加速优化、阿里云内网及专线/CEN/VPN接入等,并提供了成本优化策略和多目标发送配置指导,帮助企业构建稳定、低成本、高可用的全球日志系统。
1201 55
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
1674 3

推荐镜像

更多