mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Refine the definition of page-level freezing.
Improve comments added by commit1de58df4
which describe the lazy_scan_prune "freeze the page" path. These newly revised comments are based on suggestions from Jeff Davis. In passing, remove nearby visibility_cutoff_xid comments left over from commit6daeeb1f
. Author: Peter Geoghegan <pg@bowt.ie> Reviewed-By: Jeff Davis <pgsql@j-davis.com> Discussion: https://postgr.es/m/ebc857107fe3edd422ef8a65191ca4a8da568b9b.camel@j-davis.com
This commit is contained in:
@ -1788,13 +1788,13 @@ retry:
|
|||||||
if (tuples_frozen == 0)
|
if (tuples_frozen == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We're freezing all eligible tuples on the page, but have no
|
* We have no freeze plans to execute, so there's no added cost
|
||||||
* freeze plans to execute. This is structured as a case where
|
* from following the freeze path. That's why it was chosen.
|
||||||
* the page is nominally frozen so that we set pages all-frozen
|
* This is important in the case where the page only contains
|
||||||
* whenever no freeze plans need to be executed to make it safe.
|
* totally frozen tuples at this point (perhaps only following
|
||||||
* If this was handled via "no freeze" processing instead then
|
* pruning). Such pages can be marked all-frozen in the VM by our
|
||||||
* VACUUM would senselessly waste certain opportunities to set
|
* caller, even though none of its tuples were newly frozen here
|
||||||
* pages all-frozen (not just all-visible) at no added cost.
|
* (note that the "no freeze" path never sets pages all-frozen).
|
||||||
*
|
*
|
||||||
* We never increment the frozen_pages instrumentation counter
|
* We never increment the frozen_pages instrumentation counter
|
||||||
* here, since it only counts pages with newly frozen tuples
|
* here, since it only counts pages with newly frozen tuples
|
||||||
@ -1859,12 +1859,6 @@ retry:
|
|||||||
if (!heap_page_is_all_visible(vacrel, buf, &cutoff, &all_frozen))
|
if (!heap_page_is_all_visible(vacrel, buf, &cutoff, &all_frozen))
|
||||||
Assert(false);
|
Assert(false);
|
||||||
|
|
||||||
/*
|
|
||||||
* It's possible that we froze tuples and made the page's XID cutoff
|
|
||||||
* (for recovery conflict purposes) FrozenTransactionId. This is okay
|
|
||||||
* because visibility_cutoff_xid will be logged by our caller in a
|
|
||||||
* moment.
|
|
||||||
*/
|
|
||||||
Assert(!TransactionIdIsValid(cutoff) ||
|
Assert(!TransactionIdIsValid(cutoff) ||
|
||||||
cutoff == prunestate->visibility_cutoff_xid);
|
cutoff == prunestate->visibility_cutoff_xid);
|
||||||
}
|
}
|
||||||
|
@ -145,16 +145,14 @@ typedef struct HeapPageFreeze
|
|||||||
/*
|
/*
|
||||||
* "Freeze" NewRelfrozenXid/NewRelminMxid trackers.
|
* "Freeze" NewRelfrozenXid/NewRelminMxid trackers.
|
||||||
*
|
*
|
||||||
* Trackers used when heap_freeze_execute_prepared freezes the page, and
|
* Trackers used when heap_freeze_execute_prepared freezes, or when there
|
||||||
* when page is "nominally frozen", which happens with pages where every
|
* are zero freeze plans for a page. It is always valid for vacuumlazy.c
|
||||||
* call to heap_prepare_freeze_tuple produced no usable freeze plan.
|
* to freeze any page, by definition. This even includes pages that have
|
||||||
*
|
* no tuples with storage to consider in the first place. That way the
|
||||||
* "Nominal freezing" enables vacuumlazy.c's approach of setting a page
|
* 'totally_frozen' results from heap_prepare_freeze_tuple can always be
|
||||||
* all-frozen in the visibility map when every tuple's 'totally_frozen'
|
* used in the same way, even when no freeze plans need to be executed to
|
||||||
* result is true. That always works in the same way, independent of the
|
* "freeze the page". Only the "freeze" path needs to consider the need
|
||||||
* need to freeze tuples, and without complicating the general rule around
|
* to set pages all-frozen in the visibility map under this scheme.
|
||||||
* 'totally_frozen' results (which is that 'totally_frozen' results are
|
|
||||||
* only to be trusted with a page that goes on to be frozen by caller).
|
|
||||||
*
|
*
|
||||||
* When we freeze a page, we generally freeze all XIDs < OldestXmin, only
|
* When we freeze a page, we generally freeze all XIDs < OldestXmin, only
|
||||||
* leaving behind XIDs that are ineligible for freezing, if any. And so
|
* leaving behind XIDs that are ineligible for freezing, if any. And so
|
||||||
@ -178,11 +176,6 @@ typedef struct HeapPageFreeze
|
|||||||
* VACUUM scans a page that isn't cleanup locked. Both code paths are
|
* VACUUM scans a page that isn't cleanup locked. Both code paths are
|
||||||
* based on the same general idea (do less work for this page during the
|
* based on the same general idea (do less work for this page during the
|
||||||
* ongoing VACUUM, at the cost of having to accept older final values).
|
* ongoing VACUUM, at the cost of having to accept older final values).
|
||||||
*
|
|
||||||
* When vacuumlazy.c caller decides to do "no freeze" processing, it must
|
|
||||||
* not go on to set the page all-frozen (setting the page all-visible
|
|
||||||
* could still be okay). heap_prepare_freeze_tuple's 'totally_frozen'
|
|
||||||
* results can only be used on a page that also gets frozen as instructed.
|
|
||||||
*/
|
*/
|
||||||
TransactionId NoFreezePageRelfrozenXid;
|
TransactionId NoFreezePageRelfrozenXid;
|
||||||
MultiXactId NoFreezePageRelminMxid;
|
MultiXactId NoFreezePageRelminMxid;
|
||||||
|
Reference in New Issue
Block a user