MySQLtrx_id及其作用

2023年 10月 11日 62.2k 0

trx_id是什么?

如果单纯的理解为事务id那很容易跟其他概念混淆,如xid、query_id、lsn等,真真假假分不清。
说回trx_id,就要先说到mysql-innodb表的行格式
MySQL-trx_id及其作用-1
如图上图,其中在“记录的数据内容”中有三个隐藏列

  • 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。
下面用图解为大家详细说明
MySQL-trx_id及其作用-2

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

彩蛋

undo的清理策略:

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

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

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论