当前位置:网站首页>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计算结果全部都会出错。
边栏推荐
- MySQL卸载文档-Windows版
- Wechat applet hides the progress bar component of the video tag
- [SOC FPGA] peripheral PIO button lights up
- jmeter 函数助手 — — 随机值、随机字符串、 固定值随机提取
- Rk3399 platform development series explanation (WiFi) 5.52. Introduction to WiFi framework composition
- 高并发大流量秒杀方案思路
- 开发者别错过!飞桨黑客马拉松第三期链桨赛道报名开启
- Software testing knowledge reserve: how much do you know about the basic knowledge of "login security"?
- JVM in-depth
- 牛客小白月赛52 E.分组求对数和(二分&容斥)
猜你喜欢

安装VMmare时候提示hyper-v / device defender 侧通道安全性

Several key steps of software testing, you need to know

蚂蚁庄园安全头盔 7.8蚂蚁庄园答案

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

JVM monitoring and diagnostic tools - command line

Test the foundation of development, and teach you to prepare for a fully functional web platform environment

jmeter 函数助手 — — 随机值、随机字符串、 固定值随机提取

uniapp开发小程序如何使用微信云托管或云函数进行云开发

Shared memory for interprocess communication
![[SOC FPGA] custom IP PWM breathing lamp](/img/4b/5053137cf95e851ca89057e9b9c15c.jpg)
[SOC FPGA] custom IP PWM breathing lamp
随机推荐
How to set up in touch designer 2022 to solve the problem that leap motion is not recognized?
3531. 哈夫曼树
【解决】Final app status- UNDEFINED, exitCode- 16
Party A's requirements for those who have lost 800 yuan
POI导出Excel:设置字体、颜色、行高自适应、列宽自适应、锁住单元格、合并单元格...
Niuke Xiaobai monthly race 52 E. sum logarithms in groups (two points & inclusion and exclusion)
"Parse" focalloss to solve the problem of data imbalance
Matlab / envi principal component analysis implementation and result analysis
laravel 使用腾讯云 COS5全教程
Markdown 并排显示图片
c语言(结构体)定义一个User结构体,含以下字段:
Crudini profile editing tool
开发者别错过!飞桨黑客马拉松第三期链桨赛道报名开启
How to use wechat cloud hosting or cloud functions for cloud development of unapp development applet
Open the blue screen after VMware installation
Database notes 04
Qt多线程的多种方法之一 QThread
VMware安装后打开就蓝屏
JVM command - jmap: export memory image file & memory usage
JVM monitoring and diagnostic tools - command line