Re: Add 64-bit XIDs into PostgreSQL 15

Yura Sokolov <y.sokolov@postgrespro.ru>

From: Yura Sokolov <y.sokolov@postgrespro.ru>
To: Heikki Linnakangas <hlinnaka@iki.fi>, Maxim Orlov <orlovmg@gmail.com>, Robert Haas <robertmhaas@gmail.com>
Cc: Andres Freund <andres@anarazel.de>, Evgeny Voropaev <evgeny.voropaev@tantorlabs.com>, PostgreSQL Hackers <pgsql-hackers@postgresql.org>, Andrey Borodin <x4mmm@yandex-team.ru>
Date: 2026-02-12T13:06:01Z
Lists: pgsql-hackers
12.02.2026 12:18, Heikki Linnakangas wrote:
> One idea is that we could first introduce the 33-bit epoch system on the 
> heap pages, without changing the clog and without eliminating 
> anti-wraparound vacuums. The immediate benefit would be that when you 
> freeze a page, if there are no dead tuples, you wouldn't actually need 
> to modify the page, and wouldn't need to dirty it. The rule would be 
> that if you see an XID that's older than relfrozenxid (taking the epoch 
> into account), you can assume that it committed and is visible to everyone.
> 
> After that, as a follow-up patch, expand clog to 64 bits and eliminate 
> the need for anti-wraparound vacuums.

There is no need in 33-bit on-page epoch, imho. 32 would be enough:
- given we are limited by LSN numbers, 64bit transaction is unreachable.
  We could safely assume transaction is 63bit
- and transaction's difference on the page couldn't be larger 2^31.
  Even current patchset for 64bit transaction contains this artificial
  limitation, although it is used only to make more checks about
  correctness, and theoretically could be lifted away.
- then on-page epoch could be 32bit: 31bit difference + 32bit base = 63bit
  transaction.

In this scenario, base will contain bits from 31 to 62 of transaction, and
xmin-xmax could be a) either signed addition to base (therefore could be
negative) ie in range -2^31..2^31-1, b) or be in positive range 0..2^32-1.
In both cases difference between minimum and maximum have to be lesser than
2^31.

Case b is simpler to implement since we still need in representation of
InvalidTransactionId, BootstrapTransactionId and FrozenTransactionId.

(btw, why we still need separate BootstrapTransactionId and
FrozenTransactionId? It just because of pg_upgrade? Pitty. Completely
useless difference.)

12.02.2026 12:18, Heikki Linnakangas wrote:
> - It *will* increase the size of the database. That alone makes it a
> non-starter.

I suppose it is about "64bit xid in on-disk touple".

Size issue could be solved in alternative way: page compression. There are
already two existing and used in production implementations: one our
in-house proprietary we sell in our product, other were discussed in this
maillist couple of years ago and happily adopted by one of our competitor.

Our customers are glad to use compression since it both reduces disk space
usage and increases query performance. Although we have some issues with
integrating it with AIO. But they are solvable.

High bits of 64-bit xids in one page are mostly equal and will be
compressed really well. Yes, they still will consume memory of shared
buffers. And it is bigger issue imho.

-- 
regards
Yura Sokolov aka funny-falcon



Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Add SLRU tests for 64-bit page case

  2. Make use FullTransactionId in 2PC filenames

  3. Use larger segment file names for pg_notify

  4. Index SLRUs by 64-bit integers rather than by 32-bit integers