postgres.git / summary / log / commit / refs

commit    31a7e175fd8f6079555f2bba95c7cc118236bb20
Author:   Melanie Plageman <melanieplageman@gmail.com>
Date:     Mon Jun 02 14:54:07 2025 +0000
First released in: 18.0

    Correct heap vacuum boundary state setup ordering
    
    052026c9b9 mistakenly reordered setup steps in heap_vacuum_rel(),
    incorrectly moving RelationGetNumberOfBlocks() before
    vacuum_get_cutoffs().
    
    OldestXmin must be determined before RelationGetNumberOfBlocks()
    calculates the number of blocks in the relation that will be vacuumed.
    Otherwise tuples older than OldestXmin may be inserted into the end of
    the relation into blocks that are not vacuumed. If additional tuples
    newer than those inserted into unscanned blocks but older than
    OldestXmin are inserted into free space earlier in the relation, the
    result could be advancing pg_class.relfrozenxid to a newer value than an
    unfrozen XID in one of the unscanned heap pages.
    
    Assigning an incorrect relfrozenxid can lead to data loss, so it is
    imperative that it correctly reflect the oldest unfrozen xid.
    
    Reported-by: Peter Geoghegan <pg@bowt.ie>
    Author: Melanie Plageman <melanieplageman@gmail.com>
    Reviewed-by: Peter Geoghegan <pg@bowt.ie>
    Discussion: https://postgr.es/m/CAH2-WzntqvVEdbbpqG5JqSZGuLWmy4PBfUO-OswfivKchr2gvw%40mail.gmail.com


src/backend/access/heap/vacuumlazy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 708674d8fcf..09416450af9 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -757,7 +757,6 @@ heap_vacuum_rel(Relation rel, VacuumParams *params, vacrel->vm_new_visible_pages = 0; vacrel->vm_new_visible_frozen_pages = 0; vacrel->vm_new_frozen_pages = 0; - vacrel->rel_pages = orig_rel_pages = RelationGetNumberOfBlocks(rel); /* * Get cutoffs that determine which deleted tuples are considered DEAD, @@ -776,7 +775,9 @@ heap_vacuum_rel(Relation rel, VacuumParams *params, * to increase the number of dead tuples it can prune away.) */ vacrel->aggressive = vacuum_get_cutoffs(rel, params, &vacrel->cutoffs); + vacrel->rel_pages = orig_rel_pages = RelationGetNumberOfBlocks(rel); vacrel->vistest = GlobalVisTestFor(rel); + /* Initialize state used to track oldest extant XID/MXID */ vacrel->NewRelfrozenXid = vacrel->cutoffs.OldestXmin; vacrel->NewRelminMxid = vacrel->cutoffs.OldestMxact; [parent: fc32be3c941f]