postgres.git / summary / log / commit / refs

commit    b8386b0362b28bded0a7a00a90ac0c302b1e182a
Author:   Thomas Munro <tmunro@postgresql.org>
Date:     Wed Feb 13 00:14:10 2019 +0000
First released in: 12.0, 10.8, 11.3

    Fix rare dsa_allocate() failures due to freepage.c corruption.
    
    In a corner case, a btree page was allocated during a clean-up operation
    that could cause the tracking of the largest contiguous span of free
    space to get out of whack.  That was supposed to be prevented by the use
    of the "soft" flag to avoid allocating internal pages during incidental
    clean-up work, but the flag was ignored in the case where the FPM was
    promoted from singleton format to btree format.  Repair.
    
    Remove an obsolete comment in passing.
    
    Back-patch to 10, where freepage.c arrived (as support for dsa.c).
    
    Author: Robert Haas
    Diagnosed-by: Thomas Munro and Robert Haas
    Reported-by: Justin Pryzby, Rick Otten, Sand Stone, Arne Roland and others
    Discussion: https://postgr.es/m/CAMAYy4%2Bw3NTBM5JLWFi8twhWK4%3Dk_5L4nV5%2BbYDSPu8r4b97Zg%40mail.gmail.com


src/backend/utils/mmgr/freepage.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/mmgr/freepage.c b/src/backend/utils/mmgr/freepage.c index 5bddfefed45..7547715e1c1 100644 --- a/src/backend/utils/mmgr/freepage.c +++ b/src/backend/utils/mmgr/freepage.c @@ -1470,9 +1470,7 @@ FreePageManagerGetInternal(FreePageManager *fpm, Size npages, Size *first_page) * pages; if false, do it always. Returns 0 if the soft flag caused the * insertion to be skipped, or otherwise the size of the contiguous span * created by the insertion. This may be larger than npages if we're able - * to consolidate with an adjacent range. *internal_pages_used is set to - * true if the btree allocated pages for internal purposes, which might - * invalidate the current largest run requiring it to be recomputed. + * to consolidate with an adjacent range. */ static Size FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages, @@ -1526,6 +1524,8 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages, if (!relptr_is_null(fpm->btree_recycle)) root = FreePageBtreeGetRecycled(fpm); + else if (soft) + return 0; /* Should not allocate if soft. */ else if (FreePageManagerGetInternal(fpm, 1, &root_page)) root = (FreePageBtree *) fpm_page_to_pointer(base, root_page); else [parent: 364857f73898]