Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1c9bb02

Browse files
alvherrekaigaiAmit Langote
committed
Fix per-tuple memory leak in partition tuple routing
Some operations were being done in a longer-lived memory context,causing intra-query leaks. It's not noticeable unless you're doing alarge COPY, but if you are, it eats enough memory to cause a problem.Co-authored-by: Kohei KaiGai <kaigai@heterodb.com>Co-authored-by: Amit Langote <Langote_Amit_f8@lab.ntt.co.jp>Co-authored-by: Álvaro Herrera <alvherre@alvh.no-ip.org>Discussion:https://postgr.es/m/CAOP8fzYtVFWZADq4c=KoTAqgDrHWfng+AnEPEZccyxqxPVbbWQ@mail.gmail.com
1 parente3f99e0 commit1c9bb02

File tree

1 file changed

+41
-16
lines changed

1 file changed

+41
-16
lines changed

‎src/backend/executor/execPartition.c

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -193,9 +193,15 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
193193
Datumvalues[PARTITION_MAX_KEYS];
194194
boolisnull[PARTITION_MAX_KEYS];
195195
Relationrel;
196-
PartitionDispatchparent;
196+
PartitionDispatchdispatch;
197197
ExprContext*ecxt=GetPerTupleExprContext(estate);
198198
TupleTableSlot*ecxt_scantuple_old=ecxt->ecxt_scantuple;
199+
TupleTableSlot*myslot=NULL;
200+
MemoryContextoldcxt;
201+
HeapTupletuple;
202+
203+
/* use per-tuple context here to avoid leaking memory */
204+
oldcxt=MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
199205

200206
/*
201207
* First check the root table's partition constraint, if any. No point in
@@ -205,24 +211,23 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
205211
ExecPartitionCheck(resultRelInfo,slot,estate, true);
206212

207213
/* start with the root partitioned table */
208-
parent=pd[0];
214+
tuple=ExecFetchSlotTuple(slot);
215+
dispatch=pd[0];
209216
while (true)
210217
{
211-
TupleTableSlot*myslot=parent->tupslot;
212-
TupleConversionMap*map=parent->tupmap;
218+
TupleTableSlot*myslot=dispatch->tupslot;
219+
TupleConversionMap*map=dispatch->tupmap;
213220
intcur_index=-1;
214221

215-
rel=parent->reldesc;
222+
rel=dispatch->reldesc;
216223

217224
/*
218-
* Convert the tuple to this parent's layout so that we can do certain
219-
*things we do below.
225+
* Convert the tuple to this parent's layout, if different from the
226+
*current relation.
220227
*/
228+
myslot=dispatch->tupslot;
221229
if (myslot!=NULL&&map!=NULL)
222230
{
223-
HeapTupletuple=ExecFetchSlotTuple(slot);
224-
225-
ExecClearTuple(myslot);
226231
tuple=do_convert_tuple(tuple,map);
227232
ExecStoreTuple(tuple,myslot,InvalidBuffer, true);
228233
slot=myslot;
@@ -237,19 +242,19 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
237242
* So update ecxt_scantuple accordingly.
238243
*/
239244
ecxt->ecxt_scantuple=slot;
240-
FormPartitionKeyDatum(parent,slot,estate,values,isnull);
245+
FormPartitionKeyDatum(dispatch,slot,estate,values,isnull);
241246

242247
/*
243248
* Nothing for get_partition_for_tuple() to do if there are no
244249
* partitions to begin with.
245250
*/
246-
if (parent->partdesc->nparts==0)
251+
if (dispatch->partdesc->nparts==0)
247252
{
248253
result=-1;
249254
break;
250255
}
251256

252-
cur_index=get_partition_for_tuple(parent,values,isnull);
257+
cur_index=get_partition_for_tuple(dispatch,values,isnull);
253258

254259
/*
255260
* cur_index < 0 means we failed to find a partition of this parent.
@@ -261,15 +266,33 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
261266
result=-1;
262267
break;
263268
}
264-
elseif (parent->indexes[cur_index] >=0)
269+
elseif (dispatch->indexes[cur_index] >=0)
265270
{
266-
result=parent->indexes[cur_index];
271+
result=dispatch->indexes[cur_index];
272+
/* success! */
267273
break;
268274
}
269275
else
270-
parent=pd[-parent->indexes[cur_index]];
276+
{
277+
/* move down one level */
278+
dispatch=pd[-dispatch->indexes[cur_index]];
279+
280+
/*
281+
* Release the dedicated slot, if it was used. Create a copy of
282+
* the tuple first, for the next iteration.
283+
*/
284+
if (slot==myslot)
285+
{
286+
tuple=ExecCopySlotTuple(myslot);
287+
ExecClearTuple(myslot);
288+
}
289+
}
271290
}
272291

292+
/* Release the tuple in the lowest parent's dedicated slot. */
293+
if (slot==myslot)
294+
ExecClearTuple(myslot);
295+
273296
/* A partition was not found. */
274297
if (result<0)
275298
{
@@ -285,7 +308,9 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
285308
val_desc ?errdetail("Partition key of the failing row contains %s.",val_desc) :0));
286309
}
287310

311+
MemoryContextSwitchTo(oldcxt);
288312
ecxt->ecxt_scantuple=ecxt_scantuple_old;
313+
289314
returnresult;
290315
}
291316

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp