Skip to content

Commit 0229106

Browse files
committed
Overload index_form_tuple to allow the memory context to be supplied
40af10b changed things so we make use of a generation memory context for storing tuples to be sorted by tuplesort.c. That change does not play nicely with the changes made in 9f03ca9 (back in 2014). That commit changed things so that index_form_tuple() is called while switched into the tuplestore's tuplecontext. In order to fetch the tuple from the index, index_form_tuple() must do various memory allocations which are unrelated to the storage of the final returned tuple. Although all of these allocations are pfree'd, the fact that we now use a generation context means that the memory for these pfree'd allocations won't be used again by any other allocation due to generation.c's lack of freelists. This could result in sorts used for building indexes exceeding maintenance_work_mem by a very large amount. Here we fix it so we no longer allocate anything apart from the tuple itself into the generation context by adding a new version of index_form_tuple named index_form_tuple_context, which can be called to specify the MemoryContext to allocate the tuple into. Discussion: https://postgr.es/m/CAApHDvrHQkiFRHiGiAS-LMOvJN-eK-s762=tVzBz8ZqUea-a_A@mail.gmail.com Backpatch-through: 15, where 40af10b was added.
1 parent 2d7ead8 commit 0229106

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

src/backend/access/common/indextuple.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,39 @@
3333
* ----------------------------------------------------------------
3434
*/
3535

36+
/* ----------------
37+
* index_form_tuple
38+
*
39+
* As index_form_tuple_context, but allocates the returned tuple in the
40+
* CurrentMemoryContext.
41+
* ----------------
42+
*/
43+
IndexTuple
44+
index_form_tuple(TupleDesc tupleDescriptor,
45+
Datum *values,
46+
bool *isnull)
47+
{
48+
return index_form_tuple_context(tupleDescriptor, values, isnull,
49+
CurrentMemoryContext);
50+
}
51+
3652
/* ----------------
37-
* index_form_tuple
53+
* index_form_tuple_context
3854
*
3955
* This shouldn't leak any memory; otherwise, callers such as
4056
* tuplesort_putindextuplevalues() will be very unhappy.
4157
*
4258
* This shouldn't perform external table access provided caller
4359
* does not pass values that are stored EXTERNAL.
60+
*
61+
* Allocates returned tuple in provided 'context'.
4462
* ----------------
4563
*/
4664
IndexTuple
47-
index_form_tuple(TupleDesc tupleDescriptor,
48-
Datum *values,
49-
bool *isnull)
65+
index_form_tuple_context(TupleDesc tupleDescriptor,
66+
Datum *values,
67+
bool *isnull,
68+
MemoryContext context)
5069
{
5170
char *tp; /* tuple pointer */
5271
IndexTuple tuple; /* return tuple */
@@ -143,7 +162,7 @@ index_form_tuple(TupleDesc tupleDescriptor,
143162
size = hoff + data_size;
144163
size = MAXALIGN(size); /* be conservative */
145164

146-
tp = (char *) palloc0(size);
165+
tp = (char *) MemoryContextAllocZero(context, size);
147166
tuple = (IndexTuple) tp;
148167

149168
heap_fill_tuple(tupleDescriptor,

src/backend/utils/sort/tuplesort.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,12 +1884,13 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
18841884
ItemPointer self, Datum *values,
18851885
bool *isnull)
18861886
{
1887-
MemoryContext oldcontext = MemoryContextSwitchTo(state->tuplecontext);
1887+
MemoryContext oldcontext;
18881888
SortTuple stup;
18891889
Datum original;
18901890
IndexTuple tuple;
18911891

1892-
stup.tuple = index_form_tuple(RelationGetDescr(rel), values, isnull);
1892+
stup.tuple = index_form_tuple_context(RelationGetDescr(rel), values,
1893+
isnull, state->tuplecontext);
18931894
tuple = ((IndexTuple) stup.tuple);
18941895
tuple->t_tid = *self;
18951896
USEMEM(state, GetMemoryChunkSpace(stup.tuple));
@@ -1899,7 +1900,7 @@ tuplesort_putindextuplevalues(Tuplesortstate *state, Relation rel,
18991900
RelationGetDescr(state->indexRel),
19001901
&stup.isnull1);
19011902

1902-
MemoryContextSwitchTo(state->sortcontext);
1903+
oldcontext = MemoryContextSwitchTo(state->sortcontext);
19031904

19041905
if (!state->sortKeys || !state->sortKeys->abbrev_converter || stup.isnull1)
19051906
{

src/include/access/itup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ typedef IndexAttributeBitMapData * IndexAttributeBitMap;
150150
/* routines in indextuple.c */
151151
extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor,
152152
Datum *values, bool *isnull);
153+
extern IndexTuple index_form_tuple_context(TupleDesc tupleDescriptor,
154+
Datum *values, bool *isnull,
155+
MemoryContext context);
153156
extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
154157
TupleDesc tupleDesc);
155158
extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor,

0 commit comments

Comments
 (0)