Hello people,



            We are implementing in-memory index. As a part of that, during 
index callbacks, under CurTransactionContext, we cache all the DMLs of a 
transaction in dlist(postgres's doubly linked list).

            We registered transaction callback, and in transaction pre-commit 
event(XACT_EVENT_PRE_COMMIT), we iterate through all cached DMLs(dlist) and 
populate in my in-memory data structure.



           --> For detailed explanation of our implementation, please look 
into below thread.






               
https://www.postgresql.org/message-id/15f4ea99b34.e69a4e1b633.8937474039794097334%40zohocorp.com




           --> It was working fine until I was greeted with a segmentation 
fault while accessing dlist!

           

           --> On further examining I found that dlist head is not NULL and 
it is pointing to some address, but the container I extracted is pointing to 
0x7f7f7f7f7f7f7f5f, and I was not able to access any members in my container.



           --> 
https://wiki.postgresql.org/wiki/Developer_FAQ#Why_are_my_variables_full_of_0x7f_bytes.3F

            From the above wiki, we came to a conclusion that the memory 
context in which that dlist was present was freed.


            And yes CLOBBER_FREED_MEMORY is enabled by passing --enable-cassert 
to enable asserts in my code.



           --> Normally the memory context inside XACT_EVENT_PRE_COMMIT is 
TopTransactionContext but in this particular case, the memory context was 
'MessageContext'. Little unusual! Not sure why!



           --> So basically CurTransactionContext shouldn't get freed before 
transaction COMMIT.

           --> So what has actually happened here??? Kindly help us with 
your insights!



For your reference, a code snippet of our implementation is pasted below:



Sample code snippet:



/*** Code snippet starts ***/



dlist_head DMLInfo = {{NULL, NULL}};




Insert_callback()


{

      old_context = MemoryContextSwitchTo(CurTransactionContext);

      

      GraphIndex_InsertInfo *current;

      current = (GraphIndex_InsertInfo *)palloc(sizeof(GraphIndex_InsertInfo));

      current->tableOid = tableOid;

      current->subTransactionID = GetCurrentSubTransactionId();

      current->colValue = (long)values[0]; // Varies with column type

      current->ctid = ctid;



      dlist_push_head(&DMLInfo, &current->list_node);

      

      MemoryContextSwitchTo(old_context);

      return TRUE;

}



static void GraphIndex_xactCallback(XactEvent event, void *arg) 

{


      GraphIndex_Table *tableInfo;


      GraphIndex_InsertInfo *current;

      dlist_iter iter;



      switch (event) 

      {

              case XACT_EVENT_PRE_PREPARE:

              case XACT_EVENT_PRE_COMMIT:

              PG_TRY();

              {

                    if(DMLInfo.head.next)

                    {

                          dlist_reverse_foreach(iter, &DMLInfo)

                          {

                                current = 
dlist_container(GraphIndex_InsertInfo, list_node, iter.cur);

                                DMLProcessingFunction(current); // This is 
giving me the ERROR (while accessing members of current)

                          }

                          DMLInfo.head.next = NULL;

                    }

             }

             PG_CATCH();

             {

                   /* Do cleanup */

             }

             PG_END_TRY();



             break;



             case XACT_EVENT_ABORT:

             case XACT_EVENT_PARALLEL_ABORT:

                  /* No cleanup Necessary(No structure created) */

                  break;



             default:

                  return;

      }

}





 


 
/*** Code snippet ends ***/



Regards

G. Sai Ram







Reply via email to