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: