Re: SRF memory mgmt patch (was [HACKERS] Concern about

Поиск
Список
Период
Сортировка
От Joe Conway
Тема Re: SRF memory mgmt patch (was [HACKERS] Concern about
Дата
Msg-id 3D6EF4BD.8060908@joeconway.com
обсуждение исходный текст
Ответ на SRF memory mgmt patch (was [HACKERS] Concern about memory management with SRFs)  (Joe Conway <mail@joeconway.com>)
Список pgsql-patches
Tom Lane wrote:
> First let's see if we can figure out why the code is failing to fail
> as it stands.  The fact that it's not dumping core says there's
> something we don't understand yet ...

I'm not sure if the attached will help figure it out, but at the very
least it was eye-opening for me. I ran a test on
dblink_get_pkey('foobar') that returns 5 rows. I had a breakpoint set in
ExecClearTuple. I found that ExecClearTuple was called a total of 32
times for 5 returned rows!

Relevant to this discussion was that ExecClearTuple was called three
times, with the same slot pointer, for each function call to
dblink_get_pkey. Once in SRF_PERCALL_SETUP (per_MultiFuncCall), once in
TupleGetDatum (ExecStoreTuple), and once in FunctionNext in the loop
that builds the tuplestore.

Unfortunately I have not been able to get back to a point where I see a
coredump :(. But, that did seem to be related to calling the function
with an inappropriate declaration (now it just gives me garbage instead
of dumping core, even though I reverted the per_MultiFuncCall changes I
made earlier). I'll keep messing with this for a while, but I was hoping
the attached info would lead to some more suggestions of where to be
looking.

Thanks,

Joe
test=# select * from dblink_get_pkey('foobar');
 position | colname
----------+---------
        1 | f1
        2 | f2
        3 | f3
        4 | f4
        5 | f5
(5 rows)

- breakpoint set at ExecClearTuple
- ExecClearTuple called a total of 32 times

========================================
15 sets of 3 calls for 5 returned tuples
========================================
set 1:
------------------------------------------------------------------
this one is from: SRF_PERCALL_SETUP() == per_MultiFuncCall()
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x0817cf49 in per_MultiFuncCall (fcinfo=0xbfffe8e0) at funcapi.c:88
#2  0x400172b3 in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:911
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

this one is from: TupleGetDatum() == ExecStoreTuple()
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f3b18, slot=0x82ea07c, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x4001733f in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:941
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

this one is from: explicit call in FunctionNext()
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e9ee6 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:107
#2  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#3  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

set 2:
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x0817cf49 in per_MultiFuncCall (fcinfo=0xbfffe8e0) at funcapi.c:88
#2  0x400172b3 in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:911
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f3ac0, slot=0x82ea07c, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x4001733f in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:941
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e9ee6 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:107
#2  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#3  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

set 3:
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x0817cf49 in per_MultiFuncCall (fcinfo=0xbfffe8e0) at funcapi.c:88
#2  0x400172b3 in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:911
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f3ac0, slot=0x82ea07c, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x4001733f in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:941
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e9ee6 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:107
#2  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#3  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

set 4:
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x0817cf49 in per_MultiFuncCall (fcinfo=0xbfffe8e0) at funcapi.c:88
#2  0x400172b3 in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:911
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f3ac0, slot=0x82ea07c, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x4001733f in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:941
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e9ee6 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:107
#2  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#3  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

set 5:
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x0817cf49 in per_MultiFuncCall (fcinfo=0xbfffe8e0) at funcapi.c:88
#2  0x400172b3 in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:911
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f3ac0, slot=0x82ea07c, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x4001733f in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:941
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x080e9ee6 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:107
#2  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#3  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

=============================================================================
one set from SRF_PERCALL_SETUP() during last pass when it decides it is done
=============================================================================
#0  ExecClearTuple (slot=0x82ea07c) at execTuples.c:395
#1  0x0817cf49 in per_MultiFuncCall (fcinfo=0xbfffe8e0) at funcapi.c:88
#2  0x400172b3 in dblink_get_pkey (fcinfo=0xbfffe8e0) at dblink.c:911
#3  0x080e341a in ExecMakeFunctionResult (fcache=0x82e8d1c, arguments=0x82e8330, econtext=0x82e89bc, isNull=0xbfffeac7
"",

=============================================================================
10 sets of 2 calls for 5 returned tuples
=============================================================================
set 1:
------------------------------------------------------------------
this one is from:
return ExecStoreTuple(...
in FunctionNext
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82e8938) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82ea148, slot=0x82e8938, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x080e9f21 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:127
#3  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

this one is from:
return ExecStoreTuple(...
in ExecProject
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82e8924) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5bf8, slot=0x82e8924, buffer=0, shouldFree=1 '\001') at execTuples.c:359
#2  0x080e42cf in ExecProject (projInfo=0x82e8ca8, isDone=0xbfffeaf8) at execQual.c:2060
#3  0x080e438b in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:134
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

set 2:
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82e8938) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5ac8, slot=0x82e8938, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x080e9f21 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:127
#3  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

#0  ExecClearTuple (slot=0x82e8924) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5d9c, slot=0x82e8924, buffer=0, shouldFree=1 '\001') at execTuples.c:359
#2  0x080e42cf in ExecProject (projInfo=0x82e8ca8, isDone=0xbfffeaf8) at execQual.c:2060
#3  0x080e438b in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:134
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

set 3:
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82e8938) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5b14, slot=0x82e8938, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x080e9f21 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:127
#3  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

#0  ExecClearTuple (slot=0x82e8924) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5bf8, slot=0x82e8924, buffer=0, shouldFree=1 '\001') at execTuples.c:359
#2  0x080e42cf in ExecProject (projInfo=0x82e8ca8, isDone=0xbfffeaf8) at execQual.c:2060
#3  0x080e438b in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:134
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

set 4:
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82e8938) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5b60, slot=0x82e8938, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x080e9f21 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:127
#3  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

#0  ExecClearTuple (slot=0x82e8924) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5d9c, slot=0x82e8924, buffer=0, shouldFree=1 '\001') at execTuples.c:359
#2  0x080e42cf in ExecProject (projInfo=0x82e8ca8, isDone=0xbfffeaf8) at execQual.c:2060
#3  0x080e438b in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:134
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

set 5:
------------------------------------------------------------------
#0  ExecClearTuple (slot=0x82e8938) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5bac, slot=0x82e8938, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x080e9f21 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:127
#3  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

#0  ExecClearTuple (slot=0x82e8924) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x82f5bf8, slot=0x82e8924, buffer=0, shouldFree=1 '\001') at execTuples.c:359
#2  0x080e42cf in ExecProject (projInfo=0x82e8ca8, isDone=0xbfffeaf8) at execQual.c:2060
#3  0x080e438b in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:134
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

=============================================================================
one more sets of 2 calls - last pass to get an "all done"?
=============================================================================
#0  ExecClearTuple (slot=0x82e8938) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x0, slot=0x82e8938, buffer=0, shouldFree=0 '\0') at execTuples.c:359
#2  0x080e9f21 in FunctionNext (node=0x82e8798) at nodeFunctionscan.c:127
#3  0x080e4341 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:97
#4  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

#0  ExecClearTuple (slot=0x82e8924) at execTuples.c:395
#1  0x080e4667 in ExecStoreTuple (tuple=0x0, slot=0x82e8924, buffer=0, shouldFree=1 '\001') at execTuples.c:359
#2  0x080e4360 in ExecScan (node=0x82e8798, accessMtd=0x80e9e68 <FunctionNext>) at execScan.c:110
#3  0x080e9f3f in ExecFunctionScan (node=0x82e8798) at nodeFunctionscan.c:146

=============================================================================
2 sets - cleanup time in ExecEndFunctionScan
=============================================================================
#0  ExecClearTuple (slot=0x82e8924) at execTuples.c:395
#1  0x080ea1cc in ExecEndFunctionScan (node=0x82e8798) at nodeFunctionscan.c:318

#0  ExecClearTuple (slot=0x82e8938) at execTuples.c:395
#1  0x080ea1d5 in ExecEndFunctionScan (node=0x82e8798) at nodeFunctionscan.c:319

=============================================================================
2 sets - cleanup time in ExecDropTupleTable
=============================================================================
#0  ExecClearTuple (slot=0x82e8924) at execTuples.c:395
#1  0x080e44c9 in ExecDropTupleTable (table=0x82e8908, shouldFree=1) at execTuples.c:204

#0  ExecClearTuple (slot=0x82e8938) at execTuples.c:395
#1  0x080e44c9 in ExecDropTupleTable (table=0x82e8908, shouldFree=1) at execTuples.c:204

В списке pgsql-patches по дате отправления:

Предыдущее
От: Joe Conway
Дата:
Сообщение: Re: SRF memory mgmt patch
Следующее
От: Neil Conway
Дата:
Сообщение: Re: revised patch for PL/PgSQL table functions