diff --git a/src/backend/access/common/tidstore.c b/src/backend/access/common/tidstore.c index 629390a1f8..211d63941c 100644 --- a/src/backend/access/common/tidstore.c +++ b/src/backend/access/common/tidstore.c @@ -120,7 +120,7 @@ static void tidstore_iter_extract_tids(TidStoreIter *iter, BlockNumber blkno, * by TidStoreMemoryUsage(). */ TidStore * -TidStoreCreateLocal(size_t max_bytes) +TidStoreCreateLocal(size_t max_bytes, bool insert_only) { TidStore *ts; size_t initBlockSize = ALLOCSET_DEFAULT_INITSIZE; @@ -138,11 +138,22 @@ TidStoreCreateLocal(size_t max_bytes) maxBlockSize = ALLOCSET_DEFAULT_INITSIZE; /* Create a memory context for the TID storage */ - ts->rt_context = AllocSetContextCreate(CurrentMemoryContext, + if (insert_only) + { + ts->rt_context = BumpContextCreate(CurrentMemoryContext, "TID storage", minContextSize, initBlockSize, maxBlockSize); + } + else + { + ts->rt_context = AllocSetContextCreate(CurrentMemoryContext, + "TID storage", + minContextSize, + initBlockSize, + maxBlockSize); + } ts->tree.local = local_ts_create(ts->rt_context); diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index c3a9dc1ad6..de109acc89 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -2874,7 +2874,7 @@ dead_items_alloc(LVRelState *vacrel, int nworkers) dead_items_info->num_items = 0; vacrel->dead_items_info = dead_items_info; - vacrel->dead_items = TidStoreCreateLocal(dead_items_info->max_bytes); + vacrel->dead_items = TidStoreCreateLocal(dead_items_info->max_bytes, true); } /* @@ -2910,7 +2910,7 @@ dead_items_reset(LVRelState *vacrel) /* Recreate the tidstore with the same max_bytes limitation */ TidStoreDestroy(dead_items); - vacrel->dead_items = TidStoreCreateLocal(vacrel->dead_items_info->max_bytes); + vacrel->dead_items = TidStoreCreateLocal(vacrel->dead_items_info->max_bytes, true); /* Reset the counter */ vacrel->dead_items_info->num_items = 0; diff --git a/src/include/access/tidstore.h b/src/include/access/tidstore.h index f05d748783..32aa999519 100644 --- a/src/include/access/tidstore.h +++ b/src/include/access/tidstore.h @@ -29,7 +29,7 @@ typedef struct TidStoreIterResult OffsetNumber *offsets; } TidStoreIterResult; -extern TidStore *TidStoreCreateLocal(size_t max_bytes); +extern TidStore *TidStoreCreateLocal(size_t max_bytes, bool insert_only); extern TidStore *TidStoreCreateShared(size_t max_bytes, int tranche_id); extern TidStore *TidStoreAttach(dsa_handle area_handle, dsa_pointer handle); extern void TidStoreDetach(TidStore *ts); diff --git a/src/include/lib/radixtree.h b/src/include/lib/radixtree.h index 6f36e8bfde..6764b58b52 100644 --- a/src/include/lib/radixtree.h +++ b/src/include/lib/radixtree.h @@ -691,6 +691,7 @@ struct RT_RADIX_TREE /* leaf_context is used only for single-value leaves */ MemoryContextData *leaf_context; #endif + MemoryContextData *iter_context; }; /* @@ -1796,6 +1797,14 @@ RT_CREATE(MemoryContext ctx) tree = (RT_RADIX_TREE *) palloc0(sizeof(RT_RADIX_TREE)); tree->context = ctx; + /* + * Separate context for iteration in case the tree context doesn't support + * pfree + */ + tree->iter_context = AllocSetContextCreate(ctx, + RT_STR(RT_PREFIX) "radix_tree iter context", + ALLOCSET_SMALL_SIZES); + #ifdef RT_SHMEM tree->dsa = dsa; dp = dsa_allocate0(dsa, sizeof(RT_RADIX_TREE_CONTROL)); @@ -2038,7 +2047,7 @@ RT_BEGIN_ITERATE(RT_RADIX_TREE * tree) RT_ITER *iter; RT_CHILD_PTR root; - iter = (RT_ITER *) MemoryContextAllocZero(tree->context, + iter = (RT_ITER *) MemoryContextAllocZero(tree->iter_context, sizeof(RT_ITER)); iter->tree = tree; diff --git a/src/test/modules/test_tidstore/test_tidstore.c b/src/test/modules/test_tidstore/test_tidstore.c index 32c6c477b7..0a3a58722d 100644 --- a/src/test/modules/test_tidstore/test_tidstore.c +++ b/src/test/modules/test_tidstore/test_tidstore.c @@ -116,7 +116,8 @@ test_create(PG_FUNCTION_ARGS) dsa_pin_mapping(TidStoreGetDSA(tidstore)); } else - tidstore = TidStoreCreateLocal(tidstore_max_size); + /* VACUUM uses insert only, so we test the other option. */ + tidstore = TidStoreCreateLocal(tidstore_max_size, false); tidstore_empty_size = TidStoreMemoryUsage(tidstore);