前言
随着对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 外部的生成逻辑:
- MySQL外部保护一个全局变量global_query_id**
- 每次执行语句的时候将global_query_id -> Query_id, 而后global_query_id+1**
- 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。
当初,咱们一起来看一个事务现场:
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,后续有其余的会持续补充,心愿大家多多关注反对。