当前位置: 代码网 > it编程>数据库>Mysql > MySQL中的undo日志类型使用

MySQL中的undo日志类型使用

2025年06月26日 Mysql 我要评论
1、背景事务的回滚机制是通过undo日志来实现的,我们只需要对insrt、delete、update操作记录回滚日志,select不需要记录回滚日志,这三种操作对应的undo日志类型不同,接下来就来讲

1、背景

事务的回滚机制是通过undo日志来实现的,我们只需要对insrt、delete、update操作记录回滚日志,select不需要记录回滚日志,这三种操作对应的undo日志类型不同,接下来就来讲一下不同的操作对应的不同undo日志类型。

2、事务id

【1】分配时机

事务分为只读事务读写事务,可以通过start transaction read only语句开启一个只读事务:

只读事务不可用对普通表进行插入、删除、更新操作,但是可以对临时表进行插入、删除、更新操作,对临时表进行插入、删除、更新操作时会分配一个唯一事务id。

可以通过start transaction read write、begin、start transaction语句开启一个读写事务:

读写事务中可以进行插入、删除、更新操作,并且在插入、删除、更新时会创建一个唯一事务id。

【2】生成方式

事务id是服务器内存中的一个唯一全局变量,需要分配事务id时,就把该变量值加1分配给该事务,当该值为256的倍数时,就将该变量的值存到系统表空间的页号为5属性为max trx id占用8个字节的页中,当服务器下次重启时,将该值加上256再赋值给全局变量。

【3】隐藏列

之前讲过行的组成包含了隐藏列,由三个字段组成:row_id、trx_id、roll_pointer,这3个字段含义如下:

  • row_id:不一定存在,如果没有主键和唯一索引才存在。
  • trx_id:此条记录对应的事务id。
  • roll_pointer:指向最新的undo日志。

3、insert操作对应的undo日志

【1】trx_undo_insert_rec类型

插入一条记录,我们要将其回滚的话,最主要根据其主键将它删掉就可以,插入操作对应的回滚undo日志类型就为trx_undo_insert_rec,其组成结构如下:

在这里插入图片描述

字段含义如下:

字段含义
end of record下一条redo日志
undo type日志类型,也就是trx_undo_insert_rec
undo noundo日志编号,在事务中执行插入、删除、更新操作时从0开始递增
table id表唯一id
主键列的存储空间大小和实际值列表主键可以由多个列组成,所以这里以一个列表去存储
start of record本条redo日志地址

4、delete操作对应的undo日志

【1】delete mark阶段

页面中的行记录会根据记录头中的next_record属性组成单向链表,再根据delete_mask的标志是否删除,细分成正常记录链表垃圾链表,页的page header有一个page_free的属性,指向垃圾链表的头节点,当我们删除一条正常记录时,会先经历delete mark阶段:

将正常记录链表中被删除记录的delete_mask设置为1,但不会加入垃圾链表,在事务提交之前一直都在正常记录链表中,只是改变标志位。

【2】purge阶段

当事务提交之后,就会进入purge阶段:

后台会有线程把正常记录链表中被删除的记录移动到垃圾链表头节点处,然后更新页面中的一些其它属性:用户记录数量page_n_recs、上次插入记录位置page_last_insert、垃圾链表头节点指针page_free、页面中可重用的字节数量page_garbage等。

【3】trx_undo_del_mark_rec类型

删除操作对应的undo日志类型为trx_undo_del_mark_rec,其结构如下:

在这里插入图片描述

字段含义如下:

字段含义
end of record下一条redo日志地址
undo type日志类型,这里是trx_undo_del_mark_rec
undo noundo日志编号
table id表id
info bits记录头信息前4个比特位的值以及record_type的值
old trx_id该记录对应上一条undo日志的事务id
old roll_pointer该记录对应上一条redo日志地址
主键列的存储空间大小和实际值列表主键可以由多个列组成,所以这里以一个列表去存储
index_col_info len索引列信息占用大小
索引列位置存储空间大小和实际值列表相比于主键信息多了一个位置信息
start of record代表本条redo日志

5、update操作对应的undo日志

【1】不更新主键

不更新主键的方式分为就地更新先删除旧记录,再插入新记录,这两种更新方式对应的undo日志类型都为trx_undo_upd_exist_rec,就地更新指的是:

更新的列更新前后占用的存储空间都一样大,就直接在旧记录上进行更新。

先删除旧记录,再插入新记录指的是:

更新的列更新前后有一个列存储空间发送变化,就将旧的记录直接移动到删除链表,然后判断更新之后的记录占用的空间小于原来的空间,那就直接重用垃圾链表中的空间;否则就在页面分配一块新的空间,如果空间不够,就进行页分裂,再插入新记录。

trx_undo_upd_exist_rec类型结构如下:

在这里插入图片描述

其字段含义如下:

字段含义
end of record下一条redo日志地址
undo type日志类型,这里是trx_undo_upd_exist_rec
undo noundo日志编号
table id表id
info bits记录头信息前4个比特位的值以及record_type的值
old trx_id该记录对应上一条undo日志的事务id
old roll_pointer该记录对应上一条redo日志地址
主键列的存储空间大小和实际值列表主键可以由多个列组成,所以这里以一个列表去存储
n_updated更新列的数量
被更新列更新前位置存储空间实际值列表更新前的列的位置、存储空间、实际值
index_col_info len索引列信息占用大小
索引列位置存储空间大小和实际值列表相比于主键信息多了一个位置信息
start of record代表本条redo日志

【2】更新主键

更新主键的场景会前后产生两条undo日志,分别为删除旧记录对应的trx_undo_del_mark_rec类型undo日志和插入新记录对应的trx_undo_insert_rec类型undo日志。

6、总结

本文主要讲解了插入、删除、更新分别对应的undo日志结构,根据产生的这些undo日志就能进行事务回滚,具体的回滚方式后面再进行讲解。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

  • mysql中的数据目录用法及说明

    mysql中的数据目录用法及说明

    1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的数据都是存储在这个目录中,可以大概了解一下这个目录下是怎么存储数... [阅读全文]
  • MySQL之InnoDB存储页的独立表空间解读

    1、背景我们往一张表里插入的行数据是存储在页上的,一张页的大小为16kb,数据量大的时候一张页不可能存储完一张表里的所有数据,所以需要多张页来进行存储,这多张页所在的存储空间就叫表…

    2025年06月26日 数据库
  • MySQL中的InnoDB单表访问过程

    MySQL中的InnoDB单表访问过程

    1、背景mysql通过查询条件查询到结果的过程就叫访问方法,一条查询语句的访问方法有很多种,接下来我们就来讲一下各种访问方法。2、环境创建表:mysql>... [阅读全文]
  • MySQL 中 ROW_NUMBER() 函数最佳实践

    MySQL 中 ROW_NUMBER() 函数最佳实践

    mysql 中row_number()函数详解row_number()是 sql 窗口函数中的一种,用于为查询结果集中的每一行分配一个​​唯一的连续序号​​。与... [阅读全文]
  • MySQL中的表连接原理分析

    MySQL中的表连接原理分析

    1、背景在进行sql查询时有时需要多张表的查询结果组成一个共同的结果返回,这时就用到了mysql中连接的用法,接下来就以两张表来讲解表连接的原理。2、环境创建两... [阅读全文]
  • MySQL InnoDB中的Buffer Pool用法及说明

    MySQL InnoDB中的Buffer Pool用法及说明

    1、背景mysql数据是存储在磁盘上的,但是从磁盘上读取数据的速度太慢,所以就需要把数据从磁盘读取在内存中,申请的这块内存就叫buffer pool,也就是缓存... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com