如何在交易 ID 环绕后比较 xmin 和 txid_current()?

tom*_*mka 13 postgresql transaction postgresql-9.5

除了常规列之外,Postgres 表还有各种可用的系统列。其中之一,xmin,存储用于创建行的事务 ID。它的数据类型是xid,一个四字节整数,在某个点环绕(即不一定是唯一的)。该函数txid_current()反过来返回当前事务 ID,但作为bigint,因为它“使用“纪元”计数器进行了扩展,因此它不会在安装的生命周期内回绕”(引用手册)。

如果尚未发生交易回绕,则两个值似乎都匹配:

# CREATE TABLE test (label text);
CREATE TABLE
# INSERT INTO test VALUES ('test') RETURNING txid_current();
 txid_current 
--------------
   674500
(1 row)
INSERT 0 1
# SELECT xmin FROM test;
  xmin  
--------
 674500
(1 row)
Run Code Online (Sandbox Code Playgroud)

但我想知道:这两个值总是具有可比性吗?据我了解,txid_current()将在交易 ID 环绕(最多 2^32 个交易)后继续提供唯一值,xmin并将从零开始。这意味着两者都在那时开始返回不同的值?

如果这是真的,有没有办法来提取规则xid一的txid_current()结果,以便它匹配xmin的表(例如铸造项目txid_current(),以整数)?

编辑:更清楚地说明我关心事务 ID 环绕之后会发生什么,这很可能发生在 2^32 事务之前很久。感谢 Daniel Vérité 在评论中指出这一点。

Erw*_*ter 8

您可以剥离添加的纪元以匹配 中的值xmin,即integerbigint. 由于xmin是 typexid而不是 (signed!) integer,我们text改为比较表示:

SELECT * FROM test
WHERE  xmin::text = (txid_current() % (2^32)::bigint)::text;
Run Code Online (Sandbox Code Playgroud)

详细解释: