提交 b9058a4d 编写于 作者: M Max Yang 提交者: Yu Yang

Fix memory tuple binding leak when calling tuplestore_putvalues for tuplestore.

For instance, the simple query:
create table spilltest2 (a integer);
insert into spilltest2 select a from generate_series(1,40000000) a;
Current optimizer would generate FunctionTableScan for generate_series, which stores
result of generate_series in tuple store. Memory leak would happen because memory tuple
binding will be constructed every time in tuplestore_putvalues. It is not only memory leak
problem, also performance problem, because we don't need to construct memory tuple binding
for every row, but just once. This fix just change the interface of tuplestore_putvalues. It
will receive memory tuple binding as input, which is constructed once outside.
Signed-off-by: NXiaoran Wang <xiwang@pivotal.io>
上级 645b6473
......@@ -184,6 +184,12 @@ struct Tuplestorestate
long allowedMem; /* total memory allowed, in bytes */
long availMemMin; /* availMem low water mark (bytes) */
int64 spilledBytes; /* memory used for spilled tuples */
/*
* MemTupleBinding used for putvalues of tuplestore.
*/
MemTupleBinding *mt_bind;
};
#define COPYTUP(state,tup) ((*(state)->copytup) (state, tup))
......@@ -342,6 +348,7 @@ tuplestore_begin_heap(bool randomAccess, bool interXact, int maxKBytes)
state->copytup = copytup_heap;
state->writetup = writetup_heap;
state->readtup = readtup_heap;
state->mt_bind = NULL;
return state;
}
......@@ -450,6 +457,11 @@ tuplestore_clear(Tuplestorestate *state)
readptr->eof_reached = false;
readptr->current = 0;
}
if (state->mt_bind)
pfree(state->mt_bind);
state->mt_bind = NULL;
}
/*
......@@ -492,6 +504,8 @@ tuplestore_end(Tuplestorestate *state)
pfree(state->memtuples);
}
pfree(state->readptrs);
if (state->mt_bind)
pfree(state->mt_bind);
pfree(state);
}
......@@ -636,8 +650,13 @@ tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc,
{
MemoryContext oldcxt = MemoryContextSwitchTo(state->context);
MemTupleBinding *mt_bind = create_memtuple_binding(tdesc);
MemTuple tuple = memtuple_form_to(mt_bind, values, isnull, NULL, NULL, false);
if (!state->mt_bind)
{
state->mt_bind = create_memtuple_binding(tdesc);
Assert(state->mt_bind);
}
MemTuple tuple = memtuple_form_to(state->mt_bind, values, isnull, NULL, NULL, false);
USEMEM(state, GetMemoryChunkSpace(tuple));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册