aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2019-02-13 13:14:10 +1300
committerThomas Munro <tmunro@postgresql.org>2019-02-13 13:32:05 +1300
commit2cfdf24e7c6867c768999ccd809a32d53d226d82 (patch)
tree39a0b266152289825bf39a0e0956b8a8af7cbd81 /src
parentf5f9a760a3bc2be95f8716e476150ce128efa22b (diff)
downloadpostgresql-2cfdf24e7c6867c768999ccd809a32d53d226d82.tar.gz
postgresql-2cfdf24e7c6867c768999ccd809a32d53d226d82.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/mmgr/freepage.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/backend/utils/mmgr/freepage.c b/src/backend/utils/mmgr/freepage.c
index 7566a669708..3f352c4d77f 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