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

Commit603e153

Browse files
committed
I don't like last minute patches before the final freeze, but I believe that
this one could be useful for people experiencing out-of-memory crashes whileexecuting queries which retrieve or use a very large number of tuples.The problem happens when storage is allocated for functions results used ina large query, for example: select upper(name) from big_table; select big_table.array[1] from big_table; select count(upper(name)) from big_table;This patch is a dirty hack that fixes the out-of-memory problem for the mostcommon cases, like the above ones. It is not the final solution for theproblem but it can work for some people, so I'm posting it.The patch should be safe because all changes are under #ifdef. Furthermorethe feature can be enabled or disabled at runtime by the `free_tuple_memory'options in the pg_options file. The option is disabled by default and mustbe explicitly enabled at runtime to have any effect.To enable the patch add the follwing line to Makefile.custom:CUSTOM_COPT += -DFREE_TUPLE_MEMORYTo enable the option at runtime add the following line to pg_option:free_tuple_memory=1Massimo
1 parentbd470ba commit603e153

File tree

6 files changed

+111
-14
lines changed

6 files changed

+111
-14
lines changed

‎src/backend/access/common/heaptuple.c

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.51 1999/05/25 16:06:35 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.52 1999/06/12 14:05:36 momjian Exp $
1212
*
1313
* NOTES
1414
* The old interface functions have been converted to macros
@@ -27,6 +27,11 @@
2727
#include<storage/bufpage.h>
2828
#include<utils/memutils.h>
2929

30+
#ifdefFREE_TUPLE_MEMORY
31+
#include<utils/portal.h>
32+
#include<utils/trace.h>
33+
#endif
34+
3035
#ifndefHAVE_MEMMOVE
3136
#include<regex/utils.h>
3237
#else
@@ -93,6 +98,9 @@ DataFill(char *data,
9398
inti;
9499
intnumberOfAttributes=tupleDesc->natts;
95100
Form_pg_attribute*att=tupleDesc->attrs;
101+
#ifdefFREE_TUPLE_MEMORY
102+
boolfree_tuple_memory=pg_options[OPT_FREE_TUPLE_MEMORY];
103+
#endif
96104

97105
if (bit!=NULL)
98106
{
@@ -131,6 +139,14 @@ DataFill(char *data,
131139
*infomask |=HEAP_HASVARLENA;
132140
data_length=VARSIZE(DatumGetPointer(value[i]));
133141
memmove(data,DatumGetPointer(value[i]),data_length);
142+
#ifdefFREE_TUPLE_MEMORY
143+
/* try to pfree value[i] - dz */
144+
if (free_tuple_memory&&
145+
PortalHeapMemoryIsValid(CurrentMemoryContext,
146+
(Pointer)value[i])) {
147+
pfree(value[i]);
148+
}
149+
#endif
134150
break;
135151
casesizeof(char):
136152
*data=att[i]->attbyval ?
@@ -147,8 +163,15 @@ DataFill(char *data,
147163
*((int32*)value[i]));
148164
break;
149165
default:
150-
memmove(data,DatumGetPointer(value[i]),
151-
att[i]->attlen);
166+
memmove(data,DatumGetPointer(value[i]),att[i]->attlen);
167+
#ifdefFREE_TUPLE_MEMORY
168+
/* try to pfree value[i] - dz */
169+
if (free_tuple_memory&&
170+
PortalHeapMemoryIsValid(CurrentMemoryContext,
171+
(Pointer)value[i])) {
172+
pfree(value[i]);
173+
}
174+
#endif
152175
break;
153176
}
154177
data= (char*)att_addlength((long)data,att[i]->attlen,value[i]);

‎src/backend/executor/nodeAgg.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
#include"utils/syscache.h"
3232
#include"optimizer/clauses.h"
3333

34+
#ifdefFREE_TUPLE_MEMORY
35+
#include<utils/portal.h>
36+
#include<utils/trace.h>
37+
#endif
38+
3439
/*
3540
* AggFuncInfo -
3641
* keeps the transition functions information around
@@ -113,7 +118,9 @@ ExecAgg(Agg *node)
113118
isNull1= FALSE,
114119
isNull2= FALSE;
115120
boolqual_result;
116-
121+
#ifdefFREE_TUPLE_MEMORY
122+
boolfree_tuple_memory=pg_options[OPT_FREE_TUPLE_MEMORY];
123+
#endif
117124

118125
/* ---------------------
119126
*get state info from node
@@ -241,6 +248,10 @@ ExecAgg(Agg *node)
241248
for (;;)
242249
{
243250
TupleTableSlot*outerslot;
251+
#ifdefFREE_TUPLE_MEMORY
252+
OidvalueType;
253+
boolisByValue=0;
254+
#endif
244255

245256
isNull=isNull1=isNull2=0;
246257
outerslot=ExecProcNode(outerPlan, (Plan*)node);
@@ -293,6 +304,31 @@ ExecAgg(Agg *node)
293304
newVal=ExecEvalExpr(aggref->target,econtext,
294305
&isNull,&isDone);
295306
}
307+
#ifdefFREE_TUPLE_MEMORY
308+
if (free_tuple_memory) {
309+
switch (nodeTag(aggref->target)) {
310+
caseT_Const:
311+
isByValue= ((Const*) (aggref->target))->constbyval;
312+
break;
313+
caseT_Var:
314+
valueType= ((Var*) (aggref->target))->vartype;
315+
isByValue=typeByVal(typeidType(valueType));
316+
break;
317+
caseT_Array:
318+
isByValue= ((Array*)(aggref->target))->arrayelembyval;
319+
break;
320+
caseT_ArrayRef:
321+
isByValue=((ArrayRef*)(aggref->target))->refelembyval;
322+
break;
323+
caseT_Expr:
324+
valueType= ((Expr*) (aggref->target))->typeOid;
325+
isByValue=typeByVal(typeidType(valueType));
326+
break;
327+
default:
328+
break;
329+
}
330+
}
331+
#endif
296332

297333
if (isNull&& !aggref->usenulls)
298334
continue;/* ignore this tuple for this agg */
@@ -353,6 +389,16 @@ ExecAgg(Agg *node)
353389
(FmgrValues*)args,&isNull2);
354390
Assert(!isNull2);
355391
}
392+
393+
#ifdefFREE_TUPLE_MEMORY
394+
/* try to pfree newVal if not isByValue - dz */
395+
if (free_tuple_memory&& !isByValue&&
396+
PortalHeapMemoryIsValid(CurrentMemoryContext,
397+
(Pointer)newVal))
398+
{
399+
pfree(newVal);
400+
}
401+
#endif
356402
}
357403

358404
/*

‎src/backend/utils/misc/trace.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ static char *opt_names[] = {
7373
"syslog",/* use syslog for error messages */
7474
"hostlookup",/* enable hostname lookup in ps_status */
7575
"showportnumber",/* show port number in ps_status */
76+
#ifdefFREE_TUPLE_MEMORY
77+
"free_tuple_memory",/* try to pfree memory for each tuple */
78+
#endif
7679

7780
/* NUM_PG_OPTIONS *//* must be the last item of enum */
7881
};
@@ -404,9 +407,9 @@ read_pg_options(SIGNAL_ARGS)
404407
}
405408

406409
/*
407-
* Localvariables:
408-
*tab-width: 4
409-
*c-indent-level: 4
410-
*c-basic-offset: 4
410+
* LocalVariables:
411+
*tab-width: 4
412+
*c-indent-level: 4
413+
*c-basic-offset: 4
411414
* End:
412415
*/

‎src/backend/utils/mmgr/portalmem.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.19 1999/05/25 16:12:55 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.20 1999/06/12 14:05:39 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -289,6 +289,24 @@ PortalHeapMemoryFree(PortalHeapMemory this,
289289
}
290290
}
291291

292+
#ifdefFREE_TUPLE_MEMORY
293+
/*
294+
* PortalHeapMemoryIsValid --
295+
*
296+
* Check if a pointer is allocated in a memory context.
297+
*
298+
*/
299+
bool
300+
PortalHeapMemoryIsValid(MemoryContextcontext,Pointerpointer)
301+
{
302+
HeapMemoryBlockblock=HEAPMEMBLOCK((PortalHeapMemory)context);
303+
304+
AssertState(PointerIsValid(block));
305+
306+
return (AllocSetContains(&block->setData,pointer));
307+
}
308+
#endif
309+
292310
/* ----------------
293311
*PortalHeapMemoryRealloc
294312
* ----------------

‎src/include/utils/portal.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: portal.h,v 1.13 1999/05/25 16:14:57 momjian Exp $
9+
* $Id: portal.h,v 1.14 1999/06/1214:05:40 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -80,6 +80,10 @@ extern void EndPortalAllocMode(void);
8080
externPortalVariableMemoryPortalGetVariableMemory(Portalportal);
8181
externPortalHeapMemoryPortalGetHeapMemory(Portalportal);
8282

83+
#ifdefFREE_TUPLE_MEMORY
84+
boolPortalHeapMemoryIsValid(MemoryContextcontext,Pointerpointer);
85+
#endif
86+
8387
/* estimate of the maximum number of open portals a user would have,
8488
* used in initially sizing the PortalHashTable inEnablePortalManager()
8589
*/

‎src/include/utils/trace.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ enum pg_option_enum {
6464
OPT_SYSLOG,/* use syslog for error messages */
6565
OPT_HOSTLOOKUP,/* enable hostname lookup in ps_status */
6666
OPT_SHOWPORTNUMBER,/* show port number in ps_status */
67+
#ifdefFREE_TUPLE_MEMORY
68+
OPT_FREE_TUPLE_MEMORY,/* try to pfree memory for each tuple */
69+
#endif
6770

6871
NUM_PG_OPTIONS/* must be the last item of enum */
6972
};
@@ -83,9 +86,9 @@ extern intpg_options[NUM_PG_OPTIONS];
8386
#endif/* TRACE_H */
8487

8588
/*
86-
* Localvariables:
87-
*tab-width: 4
88-
*c-indent-level: 4
89-
*c-basic-offset: 4
89+
* LocalVariables:
90+
*tab-width: 4
91+
*c-indent-level: 4
92+
*c-basic-offset: 4
9093
* End:
9194
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp