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

Commit3df9abd

Browse files
author
Neil Conway
committed
ALTER TABLE ADD COLUMN exhibits a significant memory leak when adding a
column with a default expression. In that situation, we need to rewritethe heap relation. To evaluate the new default expression, we useExecEvalExpr(); however, this can allocate memory in the current memorycontext, and ATRewriteTable() does not switch out of the active portal'sheap memory context. The end result is a rather large memory leak (onthe order of gigabytes for a reasonably sized table).This patch changes ATRewriteTable() to switch to the per-tuple memorycontext before beginning the per-tuple loop. It also removes an explicitheap_freetuple() in the loop, since that is no longer needed.In an unrelated change, I noticed the code was scanning through theattributes of the new tuple descriptor for each tuple of the old table.I changed this to use precomputation, which should slightly speed upthe loop.Thanks to steve@deefs.net for reporting the leak.
1 parentd32b3ae commit3df9abd

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.145 2005/01/27 23:23:55 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.146 2005/02/09 23:17:26 neilc Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2460,6 +2460,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
24602460
TupleTableSlot*newslot;
24612461
HeapScanDescscan;
24622462
HeapTupletuple;
2463+
MemoryContextoldCxt;
2464+
List*dropped_attrs=NIL;
2465+
ListCell*lc;
24632466

24642467
econtext=GetPerTupleExprContext(estate);
24652468

@@ -2480,29 +2483,40 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
24802483
memset(values,0,i*sizeof(Datum));
24812484
memset(nulls,'n',i*sizeof(char));
24822485

2486+
/*
2487+
* Any attributes that are dropped according to the new tuple
2488+
* descriptor can be set to NULL. We precompute the list of
2489+
* dropped attributes to avoid needing to do so in the
2490+
* per-tuple loop.
2491+
*/
2492+
for (i=0;i<newTupDesc->natts;i++)
2493+
{
2494+
if (newTupDesc->attrs[i]->attisdropped)
2495+
dropped_attrs=lappend_int(dropped_attrs,i);
2496+
}
2497+
24832498
/*
24842499
* Scan through the rows, generating a new row if needed and then
24852500
* checking all the constraints.
24862501
*/
24872502
scan=heap_beginscan(oldrel,SnapshotNow,0,NULL);
24882503

2504+
/*
2505+
* Switch to per-tuple memory context and reset it for each
2506+
* tuple produced, so we don't leak memory.
2507+
*/
2508+
oldCxt=MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
2509+
24892510
while ((tuple=heap_getnext(scan,ForwardScanDirection))!=NULL)
24902511
{
24912512
if (newrel)
24922513
{
2493-
/*
2494-
* Extract data from old tuple. We can force to null any
2495-
* columns that are deleted according to the new tuple.
2496-
*/
2497-
intnatts=newTupDesc->natts;
2498-
2514+
/* Extract data from old tuple */
24992515
heap_deformtuple(tuple,oldTupDesc,values,nulls);
25002516

2501-
for (i=0;i<natts;i++)
2502-
{
2503-
if (newTupDesc->attrs[i]->attisdropped)
2504-
nulls[i]='n';
2505-
}
2517+
/* Set dropped attributes to null in new tuple */
2518+
foreach (lc,dropped_attrs)
2519+
nulls[lfirst_int(lc)]='n';
25062520

25072521
/*
25082522
* Process supplied expressions to replace selected
@@ -2526,6 +2540,11 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
25262540
nulls[ex->attnum-1]=' ';
25272541
}
25282542

2543+
/*
2544+
* Form the new tuple. Note that we don't explicitly
2545+
* pfree it, since the per-tuple memory context will
2546+
* be reset shortly.
2547+
*/
25292548
tuple=heap_formtuple(newTupDesc,values,nulls);
25302549
}
25312550

@@ -2572,17 +2591,14 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap)
25722591

25732592
/* Write the tuple out to the new relation */
25742593
if (newrel)
2575-
{
25762594
simple_heap_insert(newrel,tuple);
25772595

2578-
heap_freetuple(tuple);
2579-
}
2580-
25812596
ResetExprContext(econtext);
25822597

25832598
CHECK_FOR_INTERRUPTS();
25842599
}
25852600

2601+
MemoryContextSwitchTo(oldCxt);
25862602
heap_endscan(scan);
25872603
}
25882604

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp