Re: Correcting freeze conflict horizon calculation
Peter Geoghegan <pg@bowt.ie>
From: Peter Geoghegan <pg@bowt.ie>
To: Melanie Plageman <melanieplageman@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>,
Andres Freund <andres@anarazel.de>, Heikki Linnakangas <hlinnaka@iki.fi>
Date: 2025-06-02T19:05:12Z
Lists: pgsql-hackers
On Mon, Jun 2, 2025 at 2:50 PM Melanie Plageman <melanieplageman@gmail.com> wrote: > As you've explained, it will always be <= OldestXmin. And, if the > record only freezes tuples (meaning it makes no other changes to the > page) and all of those tuples' xmins were considered when calculating > prunestate->visibility_cutoff_xid, then, even if the page isn't > all-frozen, how could it be incorrect to use the > prunestate->visibility_cutoff_xid as the horizon? Obviously, it isn't safe to use prunestate->visibility_cutoff_xid unless it has actually been maintained using all of the tuples on the page. It is primarily intended for use by the VM record (though it doesn't have to continue to work that way, of course). > Why do we use > OldestXmin when the page wouldn't be all-frozen? It has always worked that way (except that it was FreezeLimit, not OldestXmin, since we could only ever freeze precisely those tuples < FreezeLimit before Postgres 16). Using prunestate->visibility_cutoff_xid instead (when that was possible) was a big improvement. You're right that in principle we could safely use a conflict horizon XID before OldestXmin in cases where we still give up and just use OldestXmin (cases where we just use "OldestXmin - 1", I should say). I'm not sure how much this matters in practice; I imagine that using prunestate->visibility_cutoff_xid is very much the common case with page-level freezing. -- Peter Geoghegan
Commits
-
Use the newest to-be-frozen xid as the conflict horizon for freezing
- c2a23dcf9e3a 19 (unreleased) landed
-
Avoid hot standby cancels from VAC FREEZE
- 66fbcb0d2e1b 9.5.0 cited