Re: Correcting freeze conflict horizon calculation

From: Melanie Plageman <melanieplageman(at)gmail(dot)com>
To: Peter Geoghegan <pg(at)bowt(dot)ie>
Cc: PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Andres Freund <andres(at)anarazel(dot)de>, Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Subject: Re: Correcting freeze conflict horizon calculation
Date: 2026-03-10 16:12:15
Message-ID: CAAKRu_a_BuFeHjbRvqCxo-a=QYWJhcmtmjZDr_GMYCt-v7AJ-Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Mar 9, 2026 at 4:15 PM Peter Geoghegan <pg(at)bowt(dot)ie> wrote:
>
> I'm not sure that you need to add any new comments above
> FreezeMultiXactId. The underlying principles that justify ignoring
> xmax when it is a multi are exactly the same as those that apply when
> xmax is a normal XID. I think that what you actually need is a single
> comment block (maybe 2) near the start of or above
> heap_prepare_freeze_tuple explaining your new snapshotConflictHorizon
> maintenance code, mentioning:
>
[...snip...]
>
> I'm trying not to be too prescriptive here; I just think that
> emphasizing high-level logical database concepts over physical
> database implementation details makes sense. I don't expect you to
> follow what I've written here all too closely. I didn't have the time
> to distill it down myself.

I've taken a stab at distilling down the comment and put it above
heap_prepare_freeze_tuple(). This is what I came up with:

* FreezePageConflictXid is advanced only for xmin/xvac freezing, not for xmax
* changes. We only remove xmax state here when it is lock-only, or when the
* updater XID (including an updater member of a MultiXact) must be aborted;
* otherwise, the tuple would already be removable. Neither case affects
* visibility on a standby.

I don't mention why we need a conflict horizon when freezing there,
but I do in the comment above the struct member:

/*
* Newest XID that this page's freeze actions will remove from tuple
* visibility metadata (currently xmin and/or xvac). It is used to derive
* the snapshot conflict horizon for a WAL record that freezes tuples. On
* a standby, we must not replay that change while any snapshot could
* still treat that XID as running.
*
* It's only used if we execute freeze plans for this page, so there is no
* corresponding "no freeze" tracker.
*/
TransactionId FreezePageConflictXid;

Do these seem correct enough and understandable?

- Melanie

Attachment Content-Type Size
v3-0001-Use-the-newest-to-be-frozen-xid-as-the-conflict-h.patch text/x-patch 6.9 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Paul A Jungwirth 2026-03-10 16:13:00 Re: SQL:2011 Application Time Update & Delete
Previous Message Matthias van de Meent 2026-03-10 16:06:41 Re: Potential security risk associated with function call