On Tue, Dec 2, 2025 at 2:39 PM Heikki Linnakangas <hlinnaka@iki.fi> wrote:
>
> A prune record can have XLogRecord->xl_xid == InvalidTransactionId, if
> the transaction hasn't been assigned a transaction ID yet. I think
> ReadNextTransactionId() - 1 would work. (Using TransactionIdRetreat
> rather than plain - 1, of course)
I was thinking about this some more, and I propose we just clear
pd_prune_xid whenever we set PD_ALL_VISIBLE like in the attached
patch.
AFAICT we weren't clearing it when setting the VM in vacuum phase III
-- which meant it would have a stale value on a normal Postgres
primary (not a promoted standby).
And we weren't initializing pd_prune_xid to InvalidTransactionId in
COPY FREEZE (though perhaps the page will be zero-initialized and thus
pd_prune_xid will read as InvalidTransactionId anyway).
So, this patch covers those cases plus clears pd_prune_xid on redo. As
previously discussed, this saves prune cycles after promotion.
I take your point that it could be worth setting pd_prune_xid to
something on the standby when there are prunable tuples left so that
we trigger a prune cycle after promotion, but since Andres didn't like
that idea and we'll update pd_prune_xid on the next delete/update
anyway, I think we don't need to do it.
Regarding Andres' idea to include pd_prune_xid to the xl_heap_prune
WAL record: I don't feel quite comfortable that pd_prune_xid would
then be half WAL-logged (since it isn't logged when update/delete sets
it). Maybe it's fine, though.
Anyway, I think my attached patch is an improvement with no risk
- Melanie