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

Commit34295b8

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 parente9bbfe6 commit34295b8

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

‎src/backend/executor/execPartition.c

Lines changed: 38 additions & 14 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,26 +211,24 @@ 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
{
211218
PartitionDescpartdesc;
212-
TupleTableSlot*myslot=parent->tupslot;
213-
TupleConversionMap*map=parent->tupmap;
219+
TupleConversionMap*map=dispatch->tupmap;
214220
intcur_index=-1;
215221

216-
rel=parent->reldesc;
222+
rel=dispatch->reldesc;
217223
partdesc=RelationGetPartitionDesc(rel);
218224

219225
/*
220-
* Convert the tuple to this parent's layout so that we can do certain
221-
*things we do below.
226+
* Convert the tuple to this parent's layout, if different from the
227+
*current relation.
222228
*/
229+
myslot=dispatch->tupslot;
223230
if (myslot!=NULL&&map!=NULL)
224231
{
225-
HeapTupletuple=ExecFetchSlotTuple(slot);
226-
227-
ExecClearTuple(myslot);
228232
tuple=do_convert_tuple(tuple,map);
229233
ExecStoreTuple(tuple,myslot,InvalidBuffer, true);
230234
slot=myslot;
@@ -239,7 +243,7 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
239243
* So update ecxt_scantuple accordingly.
240244
*/
241245
ecxt->ecxt_scantuple=slot;
242-
FormPartitionKeyDatum(parent,slot,estate,values,isnull);
246+
FormPartitionKeyDatum(dispatch,slot,estate,values,isnull);
243247

244248
/*
245249
* Nothing for get_partition_for_tuple() to do if there are no
@@ -263,15 +267,33 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
263267
result=-1;
264268
break;
265269
}
266-
elseif (parent->indexes[cur_index] >=0)
270+
elseif (dispatch->indexes[cur_index] >=0)
267271
{
268-
result=parent->indexes[cur_index];
272+
result=dispatch->indexes[cur_index];
273+
/* success! */
269274
break;
270275
}
271276
else
272-
parent=pd[-parent->indexes[cur_index]];
277+
{
278+
/* move down one level */
279+
dispatch=pd[-dispatch->indexes[cur_index]];
280+
281+
/*
282+
* Release the dedicated slot, if it was used. Create a copy of
283+
* the tuple first, for the next iteration.
284+
*/
285+
if (slot==myslot)
286+
{
287+
tuple=ExecCopySlotTuple(myslot);
288+
ExecClearTuple(myslot);
289+
}
290+
}
273291
}
274292

293+
/* Release the tuple in the lowest parent's dedicated slot. */
294+
if (slot==myslot)
295+
ExecClearTuple(myslot);
296+
275297
/* A partition was not found. */
276298
if (result<0)
277299
{
@@ -287,7 +309,9 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
287309
val_desc ?errdetail("Partition key of the failing row contains %s.",val_desc) :0));
288310
}
289311

312+
MemoryContextSwitchTo(oldcxt);
290313
ecxt->ecxt_scantuple=ecxt_scantuple_old;
314+
291315
returnresult;
292316
}
293317

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp