Facing a problem with SPI - Mailing list pgsql-hackers
| From | Gurjeet Singh |
|---|---|
| Subject | Facing a problem with SPI |
| Date | |
| Msg-id | 65937bea0612030309n2555f6b4qdacb57b31c1617ba@mail.gmail.com Whole thread Raw |
| Responses |
Re: Facing a problem with SPI
|
| List | pgsql-hackers |
<span style="font-family: courier new,monospace;">Hi all,<br /><br /> I am facing a problem with the SPI (spi.c). I
haveimplemented short-lived virtual indexes using SubTransactions. The Index Adviser, when creating virtual indexes,
createsthem inside a SubTransaction, and when it is done with its advisory stuff, it rolls back the SubTransaction.
Thisachieves two objectives: <br /><br /> (1) Easy cleanup of dependencies/changes in the catalog.<br /> (2) The
virtualindexes are not visible to other backends. This eliminates the possibility of other backends (not running in
Advisemode) seeing these indexes, as these don't have any data in them. <br /><br /> So all the index
creation/deletionis done between a pair of BeginInternalSubTransaction() (BIST()) and
RollbackAndReleaseCurrentSubTransaction()(RARCST()). This all works well when we are EXPLAINing query in special advise
mode.<br /><br /> Now, based on this, I wanted to generate advise for every query that comes for planning, be it
frompsql or pl/pgsql or anywhere else. So I made a function call to the index_adviser() from within pg_plan_query()
afterthe planner() call. <br /><br /> The problem I am facing is that that the queries being planned by pl/pgsql,
comeafter a call to SPI_connect() and SPI_Prepare(). SPI_prepare() switches to _SPI_current->execCxt memory context
using_SPI_begin_call(). <br /><br /> Everything goes well until the index_adviser() calls RARCST() to rollback it's
SubTransaction.RARCST() ultimately ends up calling AtEOSubXact_SPI(), which, just before returning, deletes the
executionmemory context of the surrounding SPI (which happens to be pl/pgsql's SPI). This, in effect, frees all the
memoryallocated by pl/pgsql for the prepare stage; and the next time the pl/pgsql's data-structures are referenced, it
causesa crash. The code in question is: <br /><br />void<br />AtEOSubXact_SPI(bool isCommit, SubTransactionId
mySubid)<br/>{<br /> bool found = false;<br /><br /> while (_SPI_connected >= 0)<br /> {<br
/> _SPI_connection *connection = &(_SPI_stack[_SPI_connected]); <br /><br /> if
(connection->connectSubid!= mySubid)<br /> break; /* couldn't be any underneath it either
*/<br/><br /> ......<br /> ......<br /> /*<br /> * If we are aborting a subtransaction and there
isan open SPI context <br /> * surrounding the subxact, clean up to prevent memory leakage.<br /> */<br />
if(_SPI_current && !isCommit)<br /> {<br /> /* free Executor memory the same as _SPI_end_call would
do*/<br /> MemoryContextResetAndDeleteChildren(_SPI_current->execCxt); <br /> ^^^^^^^^^^^<br />
/*throw away any partially created tuple-table */<br /> SPI_freetuptable(_SPI_current->tuptable);<br
/> _SPI_current->tuptable = NULL;<br /> }<br />}<br /><br /> The code is doing what the comments say,
buthow I wish it didn't. This code assumes that the latest BIST() came from a SPI invoking module, which the Index
Adviseris not! <br /><br /> I haven't been able to come up with a proof, but I think this situation can be
simulated/reproducedusing some pl/* language that we support.<br /><br /> pl/pgsql is safe, since it doesn't allow
SAVEPOINT/ROLLBACKTO SAVEPOINT inside it's code blocks; but if some pl/xxx allows SAVEPOINTS, I think it can be
reproducedusing something like: <br /><br /> SAVEPOINT xxx ( should call BIST() )<br /> SAVEPOINT
yyy ( should call BIST() )<br /> Rollback (to yyy) ( should call RARCST() ) will free pl/xxx exec
context<br/> Rollback (to xxx) ( should call RARCST() ) <br /><br /> Probably just one pair, instead of
twonested ones, should reproduce it. I tried to reproduce it using pl/pgsql's exception block (there we use BIST() and
RARCST());but couldn't succeed.<br /><br /> I hope I have understood the issue correctly, or have I missed
something?Is there a way to work around this? <br /><br />Best regards,<br clear="all" style="font-family: courier
new,monospace;"/></span><br style="font-family: courier new,monospace;" /><span style="font-family: courier
new,monospace;">--</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier
new,monospace;">gurjeet[.singh]@EnterpriseDB.com</span><brstyle="font-family: courier new,monospace;" /><span
style="font-family:courier new,monospace;">singh.gurjeet@{ gmail | hotmail | yahoo }.com </span>
pgsql-hackers by date: