暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

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

规模空前,再创历史 | 2020 PG亚洲大会圆满结束
PG ACE计划的正式发布
三期PostgreSQL国际线上沙龙活动的举办
六期PostgreSQL国内线上沙龙活动的举办

中国PostgreSQL分会与腾讯云战略合作协议签订

PostgreSQL 13.0 正式版发布通告

深度报告:开源协议那些事儿

从“非主流”到“潮流”,开源早已值得拥有

Oracle中国正在进行新一轮裁员,传 N+6 补偿

PostgreSQL与MySQL版权比较

新闻|Babelfish使PostgreSQL直接兼容SQL Server应用程序

四年三冠,PostgreSQL再度荣获“年度数据库”

更多新闻资讯行业动态技术热点,请关注中国PostgreSQL分会官方网站

https://www.postgresqlchina.com

中国PostgreSQL分会生态产品

https://www.pgfans.cn

中国PostgreSQL分会资源下载站

https://www.postgreshub.cn

点赞在看分享收藏

文章转载自开源软件联盟PostgreSQL分会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论