Re: New strategies for freezing, advancing relfrozenxid early

Jeff Davis <pgsql@j-davis.com>

From: Jeff Davis <pgsql@j-davis.com>
To: Peter Geoghegan <pg@bowt.ie>
Cc: Matthias van de Meent <boekewurm+postgres@gmail.com>, John Naylor <john.naylor@enterprisedb.com>, Andres Freund <andres@anarazel.de>, Justin Pryzby <pryzby@telsasoft.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2022-12-30T20:43:04Z
Lists: pgsql-hackers
On Mon, 2022-12-26 at 12:53 -0800, Peter Geoghegan wrote:
> * v12 merges together the code for the "freeze the page"
> lazy_scan_prune path with the block that actually calls
> heap_freeze_execute_prepared().
> 
> This should make it clear that pagefrz.freeze_required really does
> mean that freezing is required. Hopefully that addresses Jeff's
> recent
> concern. It's certainly an improvement, in any case.

Better, thank you.

> * On a related note, comments around the same point in
> lazy_scan_prune
> as well as comments above the HeapPageFreeze struct now explain a
> concept I decided to call "nominal freezing". This is the case where
> we "freeze a page" without having any freeze plans to execute.
> 
> "nominal freezing" is the new name for a concept I invented many
> months ago, which helps to resolve subtle problems with the way that
> heap_prepare_freeze_tuple is tasked with doing two different things
> for its lazy_scan_prune caller: 1. telling lazy_scan_prune how it
> would freeze each tuple (were it to freeze the page), and 2. helping
> lazy_scan_prune to determine if the page should become all-frozen in
> the VM. The latter is always conditioned on page-level freezing
> actually going ahead, since everything else in
> heap_prepare_freeze_tuple has to work that way.
> 
> We always freeze a page with zero freeze plans (or "nominally freeze"
> the page) in lazy_scan_prune (which is nothing new in itself). We
> thereby avoid breaking heap_prepare_freeze_tuple's working assumption
> that all it needs to focus on what the page will look like after
> freezing executes, while also avoiding senselessly throwing away the
> ability to set a page all-frozen in the VM in lazy_scan_prune when
> it'll cost us nothing extra. That is, by always freezing in the event
> of zero freeze plans, we won't senselessly miss out on setting a page
> all-frozen in cases where we don't actually have to execute any
> freeze
> plans to make that safe, while the "freeze the page path versus don't
> freeze the page path" dichotomy still works as a high level
> conceptual
> abstraction.

I always understood "freezing" to mean that a concrete action was
taken, and associated WAL generated.

"Nominal freezing" is happening when there are no freeze plans at all.
I get that it's to manage control flow so that the right thing happens
later. But I think it should be defined in terms of what state the page
is in so that we know that following a given path is valid. Defining
"nominal freezing" as a case where there are no freeze plans is just
confusing to me.


-- 
Jeff Davis
PostgreSQL Contributor Team - AWS





Commits

  1. Revert "Add eager and lazy freezing strategies to VACUUM."

  2. Add eager and lazy freezing strategies to VACUUM.

  3. Refine the definition of page-level freezing.

  4. Avoid special XID snapshotConflictHorizon values.

  5. Add page-level freezing to VACUUM.

  6. Remove overzealous MultiXact freeze assertion.

  7. Refactor how VACUUM passes around its XID cutoffs.

  8. Deduplicate freeze plans in freeze WAL records.

  9. Set relfrozenxid to oldest extant XID seen by VACUUM.

  10. Only skip pages marked as clean in the visibility map, if the last 32

  11. Add vacuum_freeze_table_age GUC option, to control when VACUUM should