什么是事务id(trx_id)
- 可以理解为MySQL官方存储引擎innodb维护的一个全局自增变量:max_trx_id,
- 一个6字节长度的整数。(max_trx_id如果一直增长,理论上也是有溢出的可能性的,超过2的48次方后,会重新从0开始,这时候会破坏事务的顺序规则)
- 每当一个事务开始时,需要申请一个新的trx_id值时,就获取max_trx_id的最新值,然后将max_trx_id值加1。
事务id的作用
- 主要是用来记录事务开始的顺序
- 会用在各种事务冲突和mvcc中
如何查看事务id
查看当前事务的trx_id
select TRX_ID from INFORMATION_SCHEMA.INNODB_TRX where TRX_MYSQL_THREAD_ID = CONNECTION_ID()
查看当前的事务id列表(活动)
select TRX_ID from INFORMATION_SCHEMA.INNODB_TRX
查看当前的事务id列表(活动+非活动)
看innodb status 的TRANSACTIONS 部分
show engine innodb status \G
# 找到这一部分 TRANSACTIONS 部分
TRANSACTIONS
Trx id counter 2419 -- 当前最大事务 ID
Purge done for trx's n:o < 2419 undo n:o < 0 state: running but idle
History list length 0
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421658589187480, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421658589186624, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421658589185768, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
上面是我搭的测试环境,所以没有活跃事务, 需要注意的是几个事务id都非常大(例:421658589187480) 这个后面会解释说明
什么时候获取trx_id?
MySQL5.6版本以前
当开启一个事务时,就会去获取trx_id
MySQL5.7+版本做了优化
开启一个事务,不会立即获取trx_id,只有这个事务发生了写行为,才会立即获得trx_id
优化目的
- 本身事务如果只是读数据,申请trx_id也是没用的行为
- 可以减少trx_id申请的次数
- 减少了trx_id申请过程中锁冲突的几率。
问题,只读事务的trx_id怎么办?
如果是只读的事务,用正常的trx_id的极限最大值(2^48)+trx变量的地址,这样就会得到一个非常大的形如(421658589187480)的trx_id,它肯定不会和正常的trx_id冲突。且非常好识别。
这个也是在show engine innodb status
时能看到的非常大的trx_id的原因