From 744bbad5c865d4accfca9003a2ff1ec0172312d8 Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Mon, 11 Feb 2019 10:11:39 +1300 Subject: [PATCH] Fix freepage.c bug that causes rare dsa_allocate() failures. In a corner case, a btree page was allocated during a clean-up operation that could cause the book-keeping 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. Author: Robert Haas Diagnosed-by: Robert Haas and Thomas Munro 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 d110030b63..9257235001 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 -- 2.20.1