Disable optimization when in subtransaction
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
Attachments:
ssi-subtransaction-no-optimization.patchtext/plain; name=ssi-subtransaction-no-optimization.patchDownload
*** 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))
{
"Kevin Grittner" <Kevin.Grittner@wicourts.gov> wrote:
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.
I managed to get a one-line patch wrong. Sorry. 2nd try.
-Kevin
Attachments:
ssi-subtransaction-no-optimization-v2.patchtext/plain; name=ssi-subtransaction-no-optimization-v2.patchDownload
*** a/src/backend/storage/lmgr/predicate.c
--- b/src/backend/storage/lmgr/predicate.c
***************
*** 3638,3651 **** CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
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))
{
uint32 predlockhashcode;
PREDICATELOCKTARGET *rmtarget = NULL;
--- 3638,3657 ----
if (sxact == MySerializableXact)
{
/*
! * 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 (!IsSubTransaction()
! && GET_PREDICATELOCKTARGETTAG_OFFSET(*targettag))
{
uint32 predlockhashcode;
PREDICATELOCKTARGET *rmtarget = NULL;