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

Commit50a38f6

Browse files
committed
Create memory context for HashAgg with a reasonable maxBlockSize.
If the memory context's maxBlockSize is too big, a single blockallocation can suddenly exceed work_mem. For Hash Aggregation, thiscan mean spilling to disk too early or reporting a confusing memoryusage number for EXPLAN ANALYZE.Introduce CreateWorkExprContext(), which is like CreateExprContext(),except that it creates the AllocSet with a maxBlockSize that isreasonable in proportion to work_mem.Right now, CreateWorkExprContext() is only used by Hash Aggregation,but it may be generally useful in the future.Discussion:https://postgr.es/m/412a3fbf306f84d8d78c4009e11791867e62b87c.camel@j-davis.com
1 parentf0705bb commit50a38f6

File tree

3 files changed

+58
-19
lines changed

3 files changed

+58
-19
lines changed

‎src/backend/executor/execUtils.c

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include"executor/executor.h"
5454
#include"jit/jit.h"
5555
#include"mb/pg_wchar.h"
56+
#include"miscadmin.h"
5657
#include"nodes/nodeFuncs.h"
5758
#include"parser/parsetree.h"
5859
#include"partitioning/partdesc.h"
@@ -227,21 +228,13 @@ FreeExecutorState(EState *estate)
227228
MemoryContextDelete(estate->es_query_cxt);
228229
}
229230

230-
/* ----------------
231-
*CreateExprContext
232-
*
233-
*Create a context for expression evaluation within an EState.
234-
*
235-
* An executor run may require multiple ExprContexts (we usually make one
236-
* for each Plan node, and a separate one for per-output-tuple processing
237-
* such as constraint checking). Each ExprContext has its own "per-tuple"
238-
* memory context.
239-
*
240-
* Note we make no assumption about the caller's memory context.
241-
* ----------------
231+
/*
232+
* Internal implementation for CreateExprContext() and CreateWorkExprContext()
233+
* that allows control over the AllocSet parameters.
242234
*/
243-
ExprContext*
244-
CreateExprContext(EState*estate)
235+
staticExprContext*
236+
CreateExprContextInternal(EState*estate,SizeminContextSize,
237+
SizeinitBlockSize,SizemaxBlockSize)
245238
{
246239
ExprContext*econtext;
247240
MemoryContextoldcontext;
@@ -264,7 +257,9 @@ CreateExprContext(EState *estate)
264257
econtext->ecxt_per_tuple_memory=
265258
AllocSetContextCreate(estate->es_query_cxt,
266259
"ExprContext",
267-
ALLOCSET_DEFAULT_SIZES);
260+
minContextSize,
261+
initBlockSize,
262+
maxBlockSize);
268263

269264
econtext->ecxt_param_exec_vals=estate->es_param_exec_vals;
270265
econtext->ecxt_param_list_info=estate->es_param_list_info;
@@ -294,6 +289,52 @@ CreateExprContext(EState *estate)
294289
returnecontext;
295290
}
296291

292+
/* ----------------
293+
*CreateExprContext
294+
*
295+
*Create a context for expression evaluation within an EState.
296+
*
297+
* An executor run may require multiple ExprContexts (we usually make one
298+
* for each Plan node, and a separate one for per-output-tuple processing
299+
* such as constraint checking). Each ExprContext has its own "per-tuple"
300+
* memory context.
301+
*
302+
* Note we make no assumption about the caller's memory context.
303+
* ----------------
304+
*/
305+
ExprContext*
306+
CreateExprContext(EState*estate)
307+
{
308+
returnCreateExprContextInternal(estate,ALLOCSET_DEFAULT_SIZES);
309+
}
310+
311+
312+
/* ----------------
313+
*CreateWorkExprContext
314+
*
315+
* Like CreateExprContext, but specifies the AllocSet sizes to be reasonable
316+
* in proportion to work_mem. If the maximum block allocation size is too
317+
* large, it's easy to skip right past work_mem with a single allocation.
318+
* ----------------
319+
*/
320+
ExprContext*
321+
CreateWorkExprContext(EState*estate)
322+
{
323+
SizeminContextSize=ALLOCSET_DEFAULT_MINSIZE;
324+
SizeinitBlockSize=ALLOCSET_DEFAULT_INITSIZE;
325+
SizemaxBlockSize=ALLOCSET_DEFAULT_MAXSIZE;
326+
327+
/* choose the maxBlockSize to be no larger than 1/16 of work_mem */
328+
while (16*maxBlockSize>work_mem*1024L)
329+
maxBlockSize >>=1;
330+
331+
if (maxBlockSize<ALLOCSET_DEFAULT_INITSIZE)
332+
maxBlockSize=ALLOCSET_DEFAULT_INITSIZE;
333+
334+
returnCreateExprContextInternal(estate,minContextSize,
335+
initBlockSize,maxBlockSize);
336+
}
337+
297338
/* ----------------
298339
*CreateStandaloneExprContext
299340
*

‎src/backend/executor/nodeAgg.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3277,10 +3277,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
32773277
}
32783278

32793279
if (use_hashing)
3280-
{
3281-
ExecAssignExprContext(estate,&aggstate->ss.ps);
3282-
aggstate->hashcontext=aggstate->ss.ps.ps_ExprContext;
3283-
}
3280+
aggstate->hashcontext=CreateWorkExprContext(estate);
32843281

32853282
ExecAssignExprContext(estate,&aggstate->ss.ps);
32863283

‎src/include/executor/executor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ extern void end_tup_output(TupOutputState *tstate);
493493
externEState*CreateExecutorState(void);
494494
externvoidFreeExecutorState(EState*estate);
495495
externExprContext*CreateExprContext(EState*estate);
496+
externExprContext*CreateWorkExprContext(EState*estate);
496497
externExprContext*CreateStandaloneExprContext(void);
497498
externvoidFreeExprContext(ExprContext*econtext,boolisCommit);
498499
externvoidReScanExprContext(ExprContext*econtext);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp