当前位置:网站首页>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计算结果全部都会出错。
边栏推荐
- Niuke Xiaobai monthly race 52 E. sum logarithms in groups (two points & inclusion and exclusion)
- Matlab / envi principal component analysis implementation and result analysis
- 2022Android面试必备知识点,一文全面总结
- Qt多线程的多种方法之一 QThread
- 直击2022ECDC萤石云开发者大会:携手千百行业加速智能升级
- Redis(一)——初识Redis
- Apache ab 压力测试
- 微信小程序隐藏video标签的进度条组件
- 进程间通信之共享内存
- Shared memory for interprocess communication
猜你喜欢

博士申请 | 上海交通大学自然科学研究院洪亮教授招收深度学习方向博士生

LM小型可编程控制器软件(基于CoDeSys)笔记二十三:伺服电机运行(步进电机)相对坐标转换为绝对坐标

你不知道的互联网公司招聘黑话大全

基于FPGA的VGA协议实现

Open the blue screen after VMware installation

FlexRay通信协议概述

rt-thread 中对 hardfault 的处理

JVM monitoring and diagnostic tools - command line

When we talk about immutable infrastructure, what are we talking about

Etcd database source code analysis -- starting from the start function of raftnode
随机推荐
The difference between string constants and string objects when allocating memory
vim映射大K
VMware安装后打开就蓝屏
How to set up in touch designer 2022 to solve the problem that leap motion is not recognized?
693. Travel sequencing
Basic DOS commands
Redis (II) - redis General Command
LM small programmable controller software (based on CoDeSys) Note 23: conversion of relative coordinates of servo motor operation (stepping motor) to absolute coordinates
Install mongodb database
Etcd database source code analysis -- starting from the start function of raftnode
C language (structure) defines a user structure with the following fields:
CloudCompare-点对选取
C language sorting (to be updated)
3428. Put apples
缓存在高并发场景下的常见问题
Software testing knowledge reserve: how much do you know about the basic knowledge of "login security"?
tkinter窗口选择pcd文件并显示点云(open3d)
k8s运行oracle
Niuke Xiaobai monthly race 52 E. sum logarithms in groups (two points & inclusion and exclusion)
请问如何查一篇外文文献的DOI号?