MySQL-trx_id及其作用

在这里插入图片描述

trx_id是什么?

如果单纯的理解为事务id那很容易跟其他概念混淆,如xid、query_id、lsn等,真真假假分不清。
说回trx_id,就要先说到mysql-innodb表的行格式
在这里插入图片描述
对MySQL-Innodb底层数据存储有疑问的同学可以查看MySQL-表空间之段\区\页\行

如图上图,其中在“记录的数据内容”中有三个隐藏列

  • DB_ROW_ID:占6个字节,⽤于标识⼀条记录(不⼀定存在,没有PK或者UQ的时候才有)
  • DB_TRX_ID:占6个字节,其值为inndb层的事务ID(必存在),主要用于Mvcc
  • DB_ROLL_PTR:占7个字节,其值为回滚指针(必存在)
    (大家需要注意一个点,这三个隐藏列不是每个数据页才有,而是每行数据上都有)

那么这个存在于Innodb层的trx_id到底有什么作用?
MVCC大家已经耳熟能详,多版本并发控制,在MySQL中主要解决读的并发。而trx_id在MVCC中就起到了至关重要的作用。

说一个场景:

在隔离级别为RR(可重复读)的情况下,当id=1的这条数据被用户A修改了N次,其他用户是如何做到可以重复读取第一次读过的内容,答案就是通过trx_id。
下面用图解为大家详细说明
在这里插入图片描述

  • 10:00 A用户读取id=1的数据,此时该行记录的隐藏列会产生一个trx_id,并持久化到undo上
  • 10:10 B用户修改id=1的数据,此时该行记录的隐藏列也会产生一个trx_id,并持久化到undo上,同时因为该行上已经有了一个trx_id,所以在undo中会产生一个版本链{ trx_id(1)->trx_id(2) }
  • 10:20 C用户读取id=1的数据,同上,产生trx_id,并追加在版本链上
  • 10:30 D用户读取id=1的数据,同上,产生trx_id,并追加在版本链上
  • 此时,该行数据的版本链已经为{ trx_id(1)->trx_id(2)->trx_id(3)->trx_id(4) }
  • 10:40 A用户(在没有退出会话的前提下),再次读取id=1的数据,就会直接通过undo上的版本链来重组数据并返回。

从而也就实现了“可重复读”,以及MVCC。
当然这只是trx_id的主要作用,RR和MVCC的具体实现还要涉及Readview、锁、redo等多个因素。
关于MVCC,这位老哥的文章写的非常详细了,大家可以参考一下,这里就不多赘述了。
转载-MVCC实现原理

再结合之前说过的事务完整生命周期原理,数据在被修改前都会先记录到undo,其目的也就是为了在每次原数据被修改前先保存一份,保证其他会话始终可以读到数据的历史版本。

彩蛋

undo的清理策略:

Purge Thread:事务提交后回收undo log

由 purge 线程判断是否有其它事务在使用 undo 段中表的上一个事务之前的版本信息,从而决定是否可以清理 undo log 的日志空间

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值