When I was investigating this report:
 
http://archives.postgresql.org/pgsql-bugs/2011-03/msg00349.php
 
besides providing a straightforward fix here:
 
http://archives.postgresql.org/pgsql-bugs/2011-03/msg00352.php
 
I noted that there was nearby code which needed review, as it didn't
seem safe when in a subtransaction.  Further review confirmed this
and didn't turn up any other problems in that section of code.  So,
a fix for this overreaching optimization is attached.  Note that it
is a one-line fix except for some additional comments to explain the
limitation.
 
This patch is in addition to and orthogonal to the first patch cited
above.
 
I will add this one to the 9.1 open items list.
 
-Kevin

*** a/src/backend/storage/lmgr/predicate.c
--- b/src/backend/storage/lmgr/predicate.c
***************
*** 3635,3649 **** CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
                                                 offsetof(PREDICATELOCK, 
targetLink));
  
                sxact = predlock->tag.myXact;
!               if (sxact == MySerializableXact)
                {
                        /*
!                        * If we're getting a write lock on the tuple, we don't 
need a
!                        * predicate (SIREAD) lock. At this point our 
transaction already
!                        * has an ExclusiveRowLock on the relation, so we are 
OK to drop
!                        * the predicate lock on the tuple, if found, without 
fearing that
!                        * another write against the tuple will occur before 
the MVCC
!                        * information makes it to the buffer.
                         */
                        if (GET_PREDICATELOCKTARGETTAG_OFFSET(*targettag))
                        {
--- 3635,3654 ----
                                                 offsetof(PREDICATELOCK, 
targetLink));
  
                sxact = predlock->tag.myXact;
!               if (sxact == MySerializableXact && !IsSubTransaction())
                {
                        /*
!                        * If we're getting a write lock on the tuple and we're 
not in a
!                        * subtransaction, we don't need a predicate (SIREAD) 
lock.  We
!                        * can't use this optimization within a subtransaction 
because
!                        * the subtransaction could be rolled back, and we 
would be left
!                        * without any lock at the top level.
!                        * 
!                        * At this point our transaction already has an 
ExclusiveRowLock
!                        * on the relation, so we are OK to drop the predicate 
lock on
!                        * the tuple, if found, without fearing that another 
write
!                        * against the tuple will occur before the MVCC 
information
!                        * makes it to the buffer.
                         */
                        if (GET_PREDICATELOCKTARGETTAG_OFFSET(*targettag))
                        {
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to