当前位置:网站首页>Postgresql源码(59)分析事务ID分配、溢出判断方法
Postgresql源码(59)分析事务ID分配、溢出判断方法
2022-07-07 02:05:00 【mingjie73】
xid取值规律
xid是uint32类型的,GetNewTransactionId函数中xid在ShmemVariableCache->nextXid中取值,但是ShmemVariableCache->nextXid是long int类型的。
unsigned int : 0 ~ 4294967295 ( 0 ~ 2^32-1 )
int : -2147483648 ~ 2147483647 ( -2^31 ~ 2^31-1 )
long int : -9223372036854775808 ~ 9223372036854775807 ( -2^63 ~ 2^63-1 )
GetNewTransactionId
FullTransactionId full_xid;
TransactionId xid;
full_xid = ShmemVariableCache->nextXid;
xid = XidFromFullTransactionId(full_xid);
所以xid的取值会从0到4294967295在归零再次到4294967295不停循环。而ShmemVariableCache->nextXid是一直上涨的,因为ShmemVariableCache->nextXid的范围是( -2^63 ~ 2^63-1 )。
注意ShmemVariableCache->nextXid到正数最大值9223372036854775807后在加一会溢出到负数最小值-9223372036854775808,这时强转到uint32时为0,又是一轮循环。
取值规律见下面实例:
ShmemVariableCache->nextXid
nextXid: 0 1 2 3 ... 4294967295 4294967296 4294967297 4294967298 ... 9223372036854775807
xid : 0 1 2 3 ... 4294967295 0 1 2 ... 4294967295
ShmemVariableCache->nextXid
nextXid: 9223372036854775807 -9223372036854775808 -9223372036854775807 ... 0
xid : 4294967295 0 1 0
ShmemVariableCache->nextXid自加使用FullTransactionIdAdvance函数
- 该函数从0开始增加nextXid的值,第一个if保证nextXid可以正常返回0、1、2的值
- 在后面nextXid增加到4294967296时,会走while循环把4294967296、4294967297、4294967298的值跳过,因为这三个值转换为uint32后会变成0、1、2,正常事务ID不使用这三个值。
- 在后面nextXid继续增加每次碰到上述情况,都会走while跳过这三个数的倍数。
static inline void
FullTransactionIdAdvance(FullTransactionId *dest)
{
dest->value++;
/* see FullTransactionIdAdvance() */
if (FullTransactionIdPrecedes(*dest, FirstNormalFullTransactionId))
return;
while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId)
dest->value++;
}
xid大小判断规律
已TransactionIdFollows函数为例,入参是两个uint32(0 ~ 2^32-1)。
但是做减法的时候结果保存到diff是int32(-2^31 ~ 2^31-1)。
typedef uint32 TransactionId;
/*
* TransactionIdPrecedes --- is id1 logically < id2?
*/
bool
TransactionIdPrecedes(TransactionId id1, TransactionId id2)
{
/*
* If either ID is a permanent XID then we can just do unsigned
* comparison. If both are normal, do a modulo-2^32 comparison.
*/
int32 diff;
if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
return (id1 < id2);
diff = (int32) (id1 - id2);
return (diff < 0);
}
- 注意
(id1 - id2)不管怎么减结果都是正数,因为这是两个uint32在减。这个正数结果代表这两个值的距离。
当前距离-5
id1 = 4294967290u
id2 = 4294967295u
id1 - id2 = 4294967291u
diff = (int32)(id1 - id2) = -5
id2继续增长,但是id2是uint32最大值就是4294967295u了,继续增长后溢出
id1 = 4294967290u
id2 = 10u
id1 - id2 = 4294967280u
diff = (int32)(id1 - id2) = -16
可以看到溢出后,结果仍然是负数,TransactionIdPrecedes函数的计算是正确的id1 logically < id2。
但是如果id1和id2距离过大,超过2^31后,例如id2从刚才的10继续增长到2147483647,id2领先id1的距离已经超过了2^31:
id1 = 4294967290u
id2 = 2147483647u
id1 - id2 = 2147483643u
diff = (int32)(id1 - id2) = 2147483643
结果diff又翻转了一次变成了正数,虽然id1逻辑上应该<id2,但是这时TransactionIdPrecedes的结果已经是false了。
显然TransactionIdPrecedes函数计算错误。
总结
所以在PG现有的xid分配机制上,为了保证xid回卷后还能正确的对比大小,两个xid的距离不能超过2^31。
方便记忆:事务ID可以回卷,但最老的到最新的距离不能超过20亿,否则会发生第二次符号翻转,事务ID计算结果全部都会出错。
边栏推荐
- 3531. 哈夫曼树
- When we talk about immutable infrastructure, what are we talking about
- 可极大提升编程思想与能力的书有哪些?
- MySQL(十)
- 当我们谈论不可变基础设施时,我们在谈论什么
- K8s running Oracle
- 博士申请 | 上海交通大学自然科学研究院洪亮教授招收深度学习方向博士生
- MySQL卸载文档-Windows版
- 雷特智能家居龙海祁:从专业调光到全宅智能,20年专注成就专业
- 如何解决数据库插入数据显示SQLSTATE[HY000]: General error: 1364 Field ‘xxxxx‘ doesn‘t have a default value错误
猜你喜欢

Experience sharing of contribution of "management world"

"Parse" focalloss to solve the problem of data imbalance

matlab / ENVI 主成分分析实现及结果分析

Ha Qu projection dark horse posture, only half a year to break through the 1000 yuan projector market!

字符串常量与字符串对象分配内存时的区别

JMeter's own functions are not enough? Why don't you develop one yourself

rt-thread 中对 hardfault 的处理

Overview of FlexRay communication protocol

PostgreSQL database timescaledb function time_ bucket_ Gapfill() error resolution and license replacement

Developers don't miss it! Oar hacker marathon phase III chain oar track registration opens
随机推荐
Rk3399 platform development series explanation (interruption) 13.10, workqueue work queue
基本Dos命令
JMeter's own functions are not enough? Why don't you develop one yourself
FlexRay通信协议概述
k8s运行oracle
Developers don't miss it! Oar hacker marathon phase III chain oar track registration opens
如何解决数据库插入数据显示SQLSTATE[HY000]: General error: 1364 Field ‘xxxxx‘ doesn‘t have a default value错误
JVM monitoring and diagnostic tools - command line
VIM mapping large K
Ha Qu projection dark horse posture, only half a year to break through the 1000 yuan projector market!
Subghz, lorawan, Nb IOT, Internet of things
Common problems of caching in high concurrency scenarios
C interview encryption program: input plaintext by keyboard, convert it into ciphertext through encryption program and output it to the screen.
MySQL的安装
UIC(组态UI工程)公版文件库新增7款行业素材
2022Android面试必备知识点,一文全面总结
When we talk about immutable infrastructure, what are we talking about
Force deduction 62 different paths (the number of all paths from the upper left to the lower right of the matrix) (dynamic planning)
Crudini profile editing tool
「解析」FocalLoss 解决数据不平衡问题