On Tue, 06 Apr 2021 10:46:08 +0200 Laurenz Albe <laurenz.albe@xxxxxxxxxxx> wrote: > On Sat, 2021-04-03 at 15:22 +0200, Luca Ferrari wrote: > > why having a TransactionId that is 32 bits > > in depth while it is exposed (thru txid_current()) as a 64 bits value? > > I mean, having 64 bits would reduce the need for anti-wrap arpund > > vacuum. I suspect the usage of 32 bits is both for compatibility and > > tuple header size, but I'm just guessing. > > Because there are two of these transaction IDs stored on each tuple > (xmin and xmax) to determine its visibility. The overhead of 8 bytes > per tuples for visibility is already pretty high. > > Another downside is that changing this would prevent the use of > pg_upgrade for upgrading, as the on-disk format changes. Indeed. Compatibility and size. About the txid_current() format. It is showing the 64bit format used internally. It is split in two parts: * lower part is classical XID on 32 bits, stored in tuples header * higher part is the "epoch" of the xid space, ie. the number of time the XID looped. This is not stored in tuples Look for macros EpochFromFullTransactionId and XidFromFullTransactionId in "include/access/transam.h". Given txid_current() returning eg. 10000000000: =# select txid_current(); txid_current -------------- 10000000000 The epoch would be 2: $ echo $((10000000000 >> 32)) 2 The 32bits XID stored in tuples header would be 1410065408: $ echo $((10000000000 % 2**32)) 1410065408 When looking at the NextXID in the controldata file, you would find: $ pg_controldata $PGDATA|grep NextXID Latest checkpoint's NextXID: 2:1410065408 Regards,