InnoDB的ID家族[ROW_ID,XID,TRX-ID,THREAD-ID]

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

随着对mysql的深入理解,以及接触mysql越来的频繁,发现mysql的这些ID们在整个mysql中的作用十分可观,因此对于这些ID,专门写一篇文章来让大家介绍和深入的理解,目前文章中列出来的是比较常用的和我所想到的这几个ID,后续有其他的会继续补充。


一、什么是ROW_ID?

ROW_ID

If a table has a PRIMARY KEY or UNIQUE NOT NULL index that consists of a single column that has an integer type, you can use _rowid to refer to the indexed column in SELECT statements

简单翻译一下,如果在表中存在主键非空唯一索引,并且仅由一个整数类型的列构成,那么就可以使用SELECT语句直接查询_rowid,也就是说row_id就是行索引id。
总结一下就是三个条件:

1. ,主键
2. ,非空唯一索引
3. ,整数类型

接下来看看这些条件在以下各个场景组合会发生什么?
结果就先放出来:
| 主键 | 非空唯一索引 ||--|--||  |  |

  • 若只存在主键+整型 -》 row_id生效 ,取主键值
  • 若只存在非空唯一索引+整型 -》row_id生效 ,取非空索引值
  • 若存在多个非空唯一索引 -》 row_id严格取第一个,满足就有效,第一个不满足就失效。
  • 若主键和非空唯一索引同时存在 -》row_id生效,取主键值。
  • 若主键和非空唯一索引都不存在:取全局变量dictsys.row_id

测试场景1:
设置了主键,并且主键字段是数值类型的情况下,_rowid直接引用了主键字段的值,这种叫显示rowid。
在这里插入图片描述
改了主键类型为varchar,就报错了。
在这里插入图片描述

其他的几个场景我就不在这一一举例了,有兴趣的可以自己去测试一下。

二、什么是XID?

XID
Xid 是由 server 层维护的。InnoDB 内部使用 Xid,就是为了能够在 InnoDB 事务和 server 之间做关联。
Xid 在 MySQL 内部的生成逻辑:

1. MySQL内部维护一个全局变量global_query_id
2. 每次执行语句的时候将global_query_id -> Query_id, 然后global_query_id+1
3. if(事务执行的第一条语句){Query_id->XID}

global_query_id是一个纯内存变量,重启之后清零
• 因此,在同一个数据库实例中,不同事务的XID也有可能是相同的
• MySQL重启之后,会重新生成新的binlog
保证:同一个binlog文件里,XID是唯一的
• global_query_id达到上限后,就会继续从0开始计数
因此理论上,同一个binlog还是会出现相同的XID,只是概率极低

global_query_id是8 Bytes,上限为2^64-1
• 执行一个事务,假设XID是A
• 接下来执行2^64次查询语句,让global_query_id回到A
• 再启动一个事务,这个事务的XID也是A(类似row_id超出最大值后清零,从新开始)

xid的存在的意义
redo log 和 binlog 有一个共同的数据字段,叫 XID,崩溃恢复的时候,会按顺序扫描 redo log:

  • 如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;
  • 如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。

三、什么是TRX_ID?

TRX_ID
Xid 和 InnoDB 的 trx_id 是两个容易混淆的概念。
Xid 是由 server 层维护的。InnoDB 内部使用 Xid,就是为了能够在 InnoDB 事务和 server 之间做关联。但是,InnoDB 自己的 trx_id,是另外维护的。
InnoDB 内部维护了一个 max_trx_id 全局变量,每次需要申请一个新的 trx_id 时,就获得 max_trx_id 的当前值,然后并将 max_trx_id 加 1。
InnoDB 数据可见性的核心思想是:每一行数据都记录了更新它的 trx_id,当一个事务读到一行数据的时候,判断这个数据是否可见的方法,就是通过事务的一致性视图与这行数据的 trx_id 做对比
对于正在执行的事务,你可以从 information_schema.innodb_trx 表中看到事务的 trx_id。

现在,我们一起来看一个事务现场:
http://blog.itpub.net/29654823/viewspace-2774598/

1. 事务1 时刻

session A 还没有涉及到更新,是一个只读事务。

对于只读事务,InnoDB 并不会分配 trx_id

所以事务2时刻去查事务trx_id是一个很大的值,这个很大的trx_id是由系统临时计算出来的,是把当前事务的trx变量的指针地址转成整数,再加上2^48。
为什么值这么大?
目的是要保证只读事务显示的 trx_id 值比较大,正常情况下就会区别于读写事务的 id

只读事务不分配trx_id的好处
• 可以减少事务视图里面活跃数组的大小
当前正在运行的只读事务,是不影响数据的可见性判断
因此,在创建事务的一致性视图时,只需要拷贝读写事务的trx_id
• 可以减少trx_id的申请次数
在InnoDB里,即使只执行一条普通的SELECT语句,在执行过程中,也要对应一个只读事务
如果普通查询语句不申请trx_id,就可以大大减少并发事务申请trx_id的锁冲突
由于只读事务不分配trx_id,trx_id的增加速度会变慢。
1. 事务3 时刻
此时,InnoDB才真正分配trx_id。

四、什么是THREAD_ID?

THREAD_ID
1、SHOW PROCESSLIST的第一列就是thread_id
2、系统保存了一个环境变量thread_id_counter
• 每新建一个连接,就将thread_id_counter赋值给这个新连接的线程变量
3、thread_id_counter定义为4 Bytes,因此达到2^32-1后就会重置为0
• 但不会在SHOW PROCESSLIST里面看到两个相同的thread_id
• 因为MySQL设计了一个唯一数组的逻辑,给新线程分配thread_id,逻辑代码如下

do {  new_id= thread_id_counter++;} while (!thread_ids.insert_unique(new_id).second);

以上,就是mysql中比较常用的这几个ID,后续有其他的会继续补充,希望大家多多关注支持。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
[root@QAQ ~]# sudo tail -n 50 /var/log/mysql/error.log 2023-07-14T02:45:21.370949Z 0 [Note] Shutting down plugin 'partition' 2023-07-14T02:45:21.370952Z 0 [Note] Shutting down plugin 'BLACKHOLE' 2023-07-14T02:45:21.370954Z 0 [Note] Shutting down plugin 'ARCHIVE' 2023-07-14T02:45:21.370956Z 0 [Note] Shutting down plugin 'PERFORMANCE_SCHEMA' 2023-07-14T02:45:21.370993Z 0 [Note] Shutting down plugin 'MRG_MYISAM' 2023-07-14T02:45:21.370995Z 0 [Note] Shutting down plugin 'MyISAM' 2023-07-14T02:45:21.371003Z 0 [Note] Shutting down plugin 'INNODB_SYS_VIRTUAL' 2023-07-14T02:45:21.371011Z 0 [Note] Shutting down plugin 'INNODB_SYS_DATAFILES' 2023-07-14T02:45:21.371013Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLESPACES' 2023-07-14T02:45:21.371015Z 0 [Note] Shutting down plugin 'INNODB_SYS_FOREIGN_COLS' 2023-07-14T02:45:21.371017Z 0 [Note] Shutting down plugin 'INNODB_SYS_FOREIGN' 2023-07-14T02:45:21.371018Z 0 [Note] Shutting down plugin 'INNODB_SYS_FIELDS' 2023-07-14T02:45:21.371020Z 0 [Note] Shutting down plugin 'INNODB_SYS_COLUMNS' 2023-07-14T02:45:21.371022Z 0 [Note] Shutting down plugin 'INNODB_SYS_INDEXES' 2023-07-14T02:45:21.371024Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLESTATS' 2023-07-14T02:45:21.371026Z 0 [Note] Shutting down plugin 'INNODB_SYS_TABLES' 2023-07-14T02:45:21.371028Z 0 [Note] Shutting down plugin 'INNODB_FT_INDEX_TABLE' 2023-07-14T02:45:21.371030Z 0 [Note] Shutting down plugin 'INNODB_FT_INDEX_CACHE' 2023-07-14T02:45:21.371032Z 0 [Note] Shutting down plugin 'INNODB_FT_CONFIG' 2023-07-14T02:45:21.371033Z 0 [Note] Shutting down plugin 'INNODB_FT_BEING_DELETED' 2023-07-14T02:45:21.371035Z 0 [Note] Shutting down plugin 'INNODB_FT_DELETED' 2023-07-14T02:45:21.371037Z 0 [Note] Shutting down plugin 'INNODB_FT_DEFAULT_STOPWORD' 2023-07-14T02:45:21.371039Z 0 [Note] Shutting down plugin 'INNODB_METRICS' 2023-07-14T02:45:21.371041Z 0 [Note] Shutting down plugin 'INNODB_TEMP_TABLE_INFO' 2023-07-14T02:45:21.371043Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_POOL_STATS' 2023-07-14T02:45:21.371045Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_PAGE_LRU' 2023-07-14T02:45:21.371047Z 0 [Note] Shutting down plugin 'INNODB_BUFFER_PAGE' 2023-07-14T02:45:21.371049Z 0 [Note] Shutting down plugin 'INNODB_CMP_PER_INDEX_RESET' 2023-07-14T02:45:21.371050Z 0 [Note] Shutting down plugin 'INNODB_CMP_PER_INDEX' 2023-07-14T02:45:21.371052Z 0 [Note] Shutting down plugin 'INNODB_CMPMEM_RESET' 2023-07-14T02:45:21.371054Z 0 [Note] Shutting down plugin 'INNODB_CMPMEM' 2023-07-14T02:45:21.371056Z 0 [Note] Shutting down plugin 'INNODB_CMP_RESET' 2023-07-14T02:45:21.371058Z 0 [Note] Shutting down plugin 'INNODB_CMP' 2023-07-14T02:45:21.371060Z 0 [Note] Shutting down plugin 'INNODB_LOCK_WAITS' 2023-07-14T02:45:21.371062Z 0 [Note] Shutting down plugin 'INNODB_LOCKS' 2023-07-14T02:45:21.371064Z 0 [Note] Shutting down plugin 'INNODB_TRX' 2023-07-14T02:45:21.371066Z 0 [Note] Shutting down plugin 'InnoDB' 2023-07-14T02:45:21.371100Z 0 [Note] InnoDB: FTS optimize thread exiting. 2023-07-14T02:45:21.371135Z 0 [Note] InnoDB: Starting shutdown... 2023-07-14T02:45:21.471280Z 0 [Note] InnoDB: Dumping buffer pool(s) to /www/server/data/ib_buffer_pool 2023-07-14T02:45:21.471421Z 0 [Note] InnoDB: Buffer pool(s) dump completed at 230714 10:45:21 2023-07-14T02:45:22.992635Z 0 [Note] InnoDB: Shutdown completed; log sequence number 2767468 2023-07-14T02:45:22.993964Z 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1" 2023-07-14T02:45:22.993980Z 0 [Note] Shutting down plugin 'MEMORY' 2023-07-14T02:45:22.993985Z 0 [Note] Shutting down plugin 'CSV' 2023-07-14T02:45:22.993989Z 0 [Note] Shutting down plugin 'sha256_password' 2023-07-14T02:45:22.993991Z 0 [Note] Shutting down plugin 'mysql_native_password' 2023-07-14T02:45:22.994103Z 0 [Note] Shutting down plugin 'binlog' 2023-07-14T02:45:22.994915Z 0 [Note] /www/server/mysql/bin/mysqld: Shutdown complete
07-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值