summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Naylor2024-04-07 05:27:34 +0000
committerJohn Naylor2024-04-08 07:39:49 +0000
commit8a1b31e6e59631807a08a4e9465134c343bbdf5e (patch)
tree72f147d6442438d8ce033c981a90a7b9c43a904c
parentbb766cde63b4f624d029b34c9cdd3d0a94fd5b46 (diff)
Use bump context for TID bitmaps stored by vacuum
Vacuum does not pfree individual entries, and only frees the entire storage space when finished with it. This allows using a bump context, eliminating the chunk header in each leaf allocation. Most leaf allocations will be 16 to 32 bytes, so that's a significant savings. TidStoreCreateLocal gets a boolean parameter to indicate that the created store is insert-only. This requires a separate tree context for iteration, since we free the iteration state after iteration completes. Discussion: https://postgr.es/m/CANWCAZac%3DpBePg3rhX8nXkUuaLoiAJJLtmnCfZsPEAS4EtJ%3Dkg%40mail.gmail.com Discussion: https://postgr.es/m/CANWCAZZQFfxvzO8yZHFWtQV+Z2gAMv1ku16Vu7KWmb5kZQyd1w@mail.gmail.com
-rw-r--r--src/backend/access/common/tidstore.c15
-rw-r--r--src/backend/access/heap/vacuumlazy.c4
-rw-r--r--src/include/access/tidstore.h2
-rw-r--r--src/include/lib/radixtree.h11
-rw-r--r--src/test/modules/test_tidstore/test_tidstore.c3
5 files changed, 28 insertions, 7 deletions
diff --git a/src/backend/access/common/tidstore.c b/src/backend/access/common/tidstore.c
index 629390a1f88..211d63941c2 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 c3a9dc1ad6d..de109acc89a 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 f05d7487837..32aa9995193 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 6f36e8bfde3..6764b58b52a 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 32c6c477b72..0a3a58722de 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);