PostgreSQL如何计算age

今天看到一个问题,我们在查看对象的age时,为什么索引这类对象的age总是2147483647:

bill@bill=>select relname,age(relfrozenxid) from pg_class where relname in ('t1','idx_t1');
 relname |    age
---------+------------
 t1      |        673
 t1      |        666
 t1      |        665
 t1      |          2
 idx_t1  | 2147483647
(5 rows)

可以看到表t1的age时正常的,但是其上面的索引idx_t1的age就是2147483647,这个是为什么呢?

首先我们要知道pg_class的relfrozenxid字段是什么意思,官方文档对其解释是:
“在此之前的所有事务ID在表中已经被替换为一个永久的(“冻结的”) 事务ID。 这用于跟踪表是否需要被清理,以便阻止事务ID回卷或者允许pg_xact被收缩。 如果该关系不是一个表则为0(InvalidTransactionId)。”

很显然,所有不是表的对象的该字段都是0,即:

bill@bill=>select distinct(relfrozenxid) from pg_class where relkind  not in ('r','t','f','p');
 relfrozenxid
--------------
            0
(1 row)

既然如此我们验证下便可知,xid为0的age其值便是2147483647。

bill@bill=>select age(0::text::xid);
    age
------------
 2147483647
(1 row)

那么这个又是如何得来的呢?

其实xid不过就是数据库中的一串序号,因此计算XID的“年龄”就是最简单的减法运算:

age(datfrozenxid) = txid_current() - datfrozenxid

在这里插入图片描述
那么为什么0的age是2147483647呢?
其实不仅仅是0,凡是特殊的事务id(0、1、2)的age都是2147483647:

bill@bill=>select age(1::text::xid);
    age
------------
 2147483647
(1 row)
bill@bill=>select age(2::text::xid);
    age
------------
 2147483647
(1 row)

因为在PG中特殊的事务ID一定比普通的事务ID更旧,所以将其age设置为2147483647(2^31 -1)。

参考链接:
https://stackoverflow.com/questions/54776834/how-is-agedatfrozenxid-calculated-in-postgresql
src/backend/utils/adt/xid.c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值