Skip to content

Commit 8a1b31e

Browse files
committed
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
1 parent bb766cd commit 8a1b31e

File tree

5 files changed

+28
-7
lines changed

5 files changed

+28
-7
lines changed

src/backend/access/common/tidstore.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static void tidstore_iter_extract_tids(TidStoreIter *iter, BlockNumber blkno,
120120
* by TidStoreMemoryUsage().
121121
*/
122122
TidStore *
123-
TidStoreCreateLocal(size_t max_bytes)
123+
TidStoreCreateLocal(size_t max_bytes, bool insert_only)
124124
{
125125
TidStore *ts;
126126
size_t initBlockSize = ALLOCSET_DEFAULT_INITSIZE;
@@ -138,11 +138,22 @@ TidStoreCreateLocal(size_t max_bytes)
138138
maxBlockSize = ALLOCSET_DEFAULT_INITSIZE;
139139

140140
/* Create a memory context for the TID storage */
141-
ts->rt_context = AllocSetContextCreate(CurrentMemoryContext,
141+
if (insert_only)
142+
{
143+
ts->rt_context = BumpContextCreate(CurrentMemoryContext,
142144
"TID storage",
143145
minContextSize,
144146
initBlockSize,
145147
maxBlockSize);
148+
}
149+
else
150+
{
151+
ts->rt_context = AllocSetContextCreate(CurrentMemoryContext,
152+
"TID storage",
153+
minContextSize,
154+
initBlockSize,
155+
maxBlockSize);
156+
}
146157

147158
ts->tree.local = local_ts_create(ts->rt_context);
148159

src/backend/access/heap/vacuumlazy.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2874,7 +2874,7 @@ dead_items_alloc(LVRelState *vacrel, int nworkers)
28742874
dead_items_info->num_items = 0;
28752875
vacrel->dead_items_info = dead_items_info;
28762876

2877-
vacrel->dead_items = TidStoreCreateLocal(dead_items_info->max_bytes);
2877+
vacrel->dead_items = TidStoreCreateLocal(dead_items_info->max_bytes, true);
28782878
}
28792879

28802880
/*
@@ -2910,7 +2910,7 @@ dead_items_reset(LVRelState *vacrel)
29102910

29112911
/* Recreate the tidstore with the same max_bytes limitation */
29122912
TidStoreDestroy(dead_items);
2913-
vacrel->dead_items = TidStoreCreateLocal(vacrel->dead_items_info->max_bytes);
2913+
vacrel->dead_items = TidStoreCreateLocal(vacrel->dead_items_info->max_bytes, true);
29142914

29152915
/* Reset the counter */
29162916
vacrel->dead_items_info->num_items = 0;

src/include/access/tidstore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ typedef struct TidStoreIterResult
2929
OffsetNumber *offsets;
3030
} TidStoreIterResult;
3131

32-
extern TidStore *TidStoreCreateLocal(size_t max_bytes);
32+
extern TidStore *TidStoreCreateLocal(size_t max_bytes, bool insert_only);
3333
extern TidStore *TidStoreCreateShared(size_t max_bytes, int tranche_id);
3434
extern TidStore *TidStoreAttach(dsa_handle area_handle, dsa_pointer handle);
3535
extern void TidStoreDetach(TidStore *ts);

src/include/lib/radixtree.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ struct RT_RADIX_TREE
691691
/* leaf_context is used only for single-value leaves */
692692
MemoryContextData *leaf_context;
693693
#endif
694+
MemoryContextData *iter_context;
694695
};
695696

696697
/*
@@ -1796,6 +1797,14 @@ RT_CREATE(MemoryContext ctx)
17961797
tree = (RT_RADIX_TREE *) palloc0(sizeof(RT_RADIX_TREE));
17971798
tree->context = ctx;
17981799

1800+
/*
1801+
* Separate context for iteration in case the tree context doesn't support
1802+
* pfree
1803+
*/
1804+
tree->iter_context = AllocSetContextCreate(ctx,
1805+
RT_STR(RT_PREFIX) "radix_tree iter context",
1806+
ALLOCSET_SMALL_SIZES);
1807+
17991808
#ifdef RT_SHMEM
18001809
tree->dsa = dsa;
18011810
dp = dsa_allocate0(dsa, sizeof(RT_RADIX_TREE_CONTROL));
@@ -2038,7 +2047,7 @@ RT_BEGIN_ITERATE(RT_RADIX_TREE * tree)
20382047
RT_ITER *iter;
20392048
RT_CHILD_PTR root;
20402049

2041-
iter = (RT_ITER *) MemoryContextAllocZero(tree->context,
2050+
iter = (RT_ITER *) MemoryContextAllocZero(tree->iter_context,
20422051
sizeof(RT_ITER));
20432052
iter->tree = tree;
20442053

src/test/modules/test_tidstore/test_tidstore.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ test_create(PG_FUNCTION_ARGS)
116116
dsa_pin_mapping(TidStoreGetDSA(tidstore));
117117
}
118118
else
119-
tidstore = TidStoreCreateLocal(tidstore_max_size);
119+
/* VACUUM uses insert only, so we test the other option. */
120+
tidstore = TidStoreCreateLocal(tidstore_max_size, false);
120121

121122
tidstore_empty_size = TidStoreMemoryUsage(tidstore);
122123

0 commit comments

Comments
 (0)