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

Commit5561404

Browse files
committed
Avoid query-lifetime memory leaks in XMLTABLE (bug #15321)
Multiple calls to XMLTABLE in a query (e.g. laterally applying it to atable with an xml column, an important use-case) were leaking largeamounts of memory into the per-query context, blowing up memory usage.Repair by reorganizing memory context usage in nodeTableFuncscan; usethe usual per-tuple context for row-by-row evaluations instead ofperValueCxt, and use the explicitly created context -- renamed fromperValueCxt to perTableCxt -- for arguments and state for eachindividual table-generation operation.Backpatch to PG10 where this code was introduced.Original report by IRC user begriffs; analysis and patch by me.Reviewed by Tom Lane and Pavel Stehule.Discussion:https://postgr.es/m/153394403528.10284.7530399040974170549@wrigleys.postgresql.org
1 parent26853a8 commit5561404

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

‎src/backend/executor/nodeTableFuncscan.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags)
170170
/* Only XMLTABLE is supported currently */
171171
scanstate->routine=&XmlTableRoutine;
172172

173-
scanstate->perValueCxt=
173+
scanstate->perTableCxt=
174174
AllocSetContextCreate(CurrentMemoryContext,
175175
"TableFunc per value context",
176176
ALLOCSET_DEFAULT_SIZES);
@@ -288,6 +288,16 @@ tfuncFetchRows(TableFuncScanState *tstate, ExprContext *econtext)
288288
oldcxt=MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
289289
tstate->tupstore=tuplestore_begin_heap(false, false,work_mem);
290290

291+
/*
292+
* Each call to fetch a new set of rows - of which there may be very many
293+
* if XMLTABLE is being used in a lateral join - will allocate a possibly
294+
* substantial amount of memory, so we cannot use the per-query context
295+
* here. perTableCxt now serves the same function as "argcontext" does in
296+
* FunctionScan - a place to store per-one-call (i.e. one result table)
297+
* lifetime data (as opposed to per-query or per-result-tuple).
298+
*/
299+
MemoryContextSwitchTo(tstate->perTableCxt);
300+
291301
PG_TRY();
292302
{
293303
routine->InitOpaque(tstate,
@@ -319,15 +329,17 @@ tfuncFetchRows(TableFuncScanState *tstate, ExprContext *econtext)
319329
}
320330
PG_END_TRY();
321331

322-
/* return to original memory context, and clean up */
323-
MemoryContextSwitchTo(oldcxt);
332+
/* clean up and return to original memory context */
324333

325334
if (tstate->opaque!=NULL)
326335
{
327336
routine->DestroyOpaque(tstate);
328337
tstate->opaque=NULL;
329338
}
330339

340+
MemoryContextSwitchTo(oldcxt);
341+
MemoryContextReset(tstate->perTableCxt);
342+
331343
return;
332344
}
333345

@@ -433,7 +445,14 @@ tfuncLoadRows(TableFuncScanState *tstate, ExprContext *econtext)
433445

434446
ordinalitycol=
435447
((TableFuncScan*) (tstate->ss.ps.plan))->tablefunc->ordinalitycol;
436-
oldcxt=MemoryContextSwitchTo(tstate->perValueCxt);
448+
449+
/*
450+
* We need a short-lived memory context that we can clean up each time
451+
* around the loop, to avoid wasting space. Our default per-tuple context
452+
* is fine for the job, since we won't have used it for anything yet in
453+
* this tuple cycle.
454+
*/
455+
oldcxt=MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
437456

438457
/*
439458
* Keep requesting rows from the table builder until there aren't any.
@@ -496,7 +515,7 @@ tfuncLoadRows(TableFuncScanState *tstate, ExprContext *econtext)
496515

497516
tuplestore_putvalues(tstate->tupstore,tupdesc,values,nulls);
498517

499-
MemoryContextReset(tstate->perValueCxt);
518+
MemoryContextReset(econtext->ecxt_per_tuple_memory);
500519
}
501520

502521
MemoryContextSwitchTo(oldcxt);

‎src/include/nodes/execnodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1484,7 +1484,7 @@ typedef struct TableFuncScanState
14841484
FmgrInfo*in_functions;/* input function for each column */
14851485
Oid*typioparams;/* typioparam for each column */
14861486
int64ordinal;/* row number to be output next */
1487-
MemoryContextperValueCxt;/*short lifecontext for value evaluation */
1487+
MemoryContextperTableCxt;/*per-tablecontext */
14881488
Tuplestorestate*tupstore;/* output tuple store */
14891489
}TableFuncScanState;
14901490

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp