MySQL中的undo日志类型使用

 更新时间:2025年06月26日 08:55:57   作者:在成都搬砖的鸭鸭  
这篇文章主要介绍了MySQL中的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日志就能进行事务回滚,具体的回滚方式后面再进行讲解。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • MySQL安装后不能用是什么情况该如何解决

    MySQL安装后不能用是什么情况该如何解决

    之前安装过MYSQL好像不用手动启动服务,具体也忘记了,但我上回给公司安装的那个是要手动安装服务的,如果mysql刚刚安装不能用,可能是服务没有安装
    2014-03-03
  • MySQL执行时间的查询

    MySQL执行时间的查询

    这篇文章主要介绍了MySQL执行时间的查询,查询频繁的数据库和查询执行时间长的sql,文章中有详细的代码实例,感兴趣的同学可以参考阅读
    2023-04-04
  • 解决Navicat for Mysql连接报错1251的问题(连接失败)

    解决Navicat for Mysql连接报错1251的问题(连接失败)

    记得在之前给大家介绍过Navicat for Mysql连接报错的问题,可能写的不够详细,今天在稍作修改补充下,对Navicat for Mysql连接报错1251问题感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • mysql如何将多行数据合并成一行

    mysql如何将多行数据合并成一行

    这篇文章主要介绍了mysql将多行数据合并成一行的方法,需要的朋友可以参考下
    2014-08-08
  • Mysql 根据一个表数据更新另一个表的某些字段(sql语句)

    Mysql 根据一个表数据更新另一个表的某些字段(sql语句)

    这篇文章主要介绍了Mysql 根据一个表数据更新另一个表的某些字段,本文给出了sql语句,感兴趣的朋友可以跟随脚本之家小编一起学习吧
    2018-05-05
  • MySQL重置root密码提示

    MySQL重置root密码提示"Unknown column ‘password"的解决方法

    这篇文章主要介绍了MySQL重置root密码提示"Unknown column ‘password"的解决方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-02-02
  • mysql 使用inet_aton和inet_ntoa处理ip地址数据的实例

    mysql 使用inet_aton和inet_ntoa处理ip地址数据的实例

    下面小编就为大家带来一篇mysql 使用inet_aton和inet_ntoa处理ip地址数据的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • MySQL8.0 Undo Tablespace管理详解

    MySQL8.0 Undo Tablespace管理详解

    本文主要介绍了MySQL8.0 Undo Tablespace管理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • MySQL分组查询Group By实现原理详解

    MySQL分组查询Group By实现原理详解

    在MySQL 中,GROUP BY 的实现同样有多种(三种)方式,其中有两种方式会利用现有的索引信息来完成 GROUP BY,另外一种为完全无法使用索引的场景下使用。下面我们分别针对这三种实现方式做一个分析
    2016-05-05
  • Mysql动态更新数据库脚本的示例讲解

    Mysql动态更新数据库脚本的示例讲解

    今天小编就为大家分享一篇关于Mysql动态更新数据库脚本的示例讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论