Thread: Wrong FOR UPDATE lock type

Wrong FOR UPDATE lock type

From
Jan Wieck
Date:
Hi,
   I'm  about  99.666667% sure that the lock type choosen in the   FOR UPDATE case (line  511  of  parse_relation.c)
should be   RowExclusiveLock  instead  of  RowShareLock.   Actually I get   "Deadlock risk" debug messages when
selectingFOR UPDATE  and   then really UPDATE.
 
   Should I change it?


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #




RE: Wrong FOR UPDATE lock type

From
"Mikheev, Vadim"
Date:
>     I'm  about  99.666667% sure that the lock type choosen in the
>     FOR UPDATE case (line  511  of  parse_relation.c)  should  be
>     RowExclusiveLock  instead  of  RowShareLock.   Actually I get
>     "Deadlock risk" debug messages when selecting FOR UPDATE  and
>     then really UPDATE.

http://www.postgresql.org/users-lounge/docs/6.5/user/x3116.htm

RowShareLock
Acquired by SELECT FOR UPDATE and LOCK TABLE for IN ROW SHARE MODE
statements. 

Conflicts with ExclusiveLock and AccessExclusiveLock modes. 

Vadim


Re: Wrong FOR UPDATE lock type

From
Jan Wieck
Date:
Mikheev, Vadim wrote:
> >     I'm  about  99.666667% sure that the lock type choosen in the
> >     FOR UPDATE case (line  511  of  parse_relation.c)  should  be
> >     RowExclusiveLock  instead  of  RowShareLock.   Actually I get
> >     "Deadlock risk" debug messages when selecting FOR UPDATE  and
> >     then really UPDATE.
>
> http://www.postgresql.org/users-lounge/docs/6.5/user/x3116.htm
>
> RowShareLock
> Acquired by SELECT FOR UPDATE and LOCK TABLE for IN ROW SHARE MODE
> statements.
>
> Conflicts with ExclusiveLock and AccessExclusiveLock modes.
   Tom,
   IIRC  the  "Deadlock risk" debug message is from you. I think   it must get a little smarter. IMHO an application
thatwant's   to  UPDATE  something  in  a  transaction but must SELECT the   row(s) first to do it's own calculation on
them, should  use   SELECT FOR UPDATE. Is that debug output really appropriate in   this case (it raises from
RowShareLock to  RowExclusiveLock   because  of  the  UPDATE  of the previous FOR UPDATE selected   row)?
 


Jan

--

#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #




Re: Wrong FOR UPDATE lock type

From
Tom Lane
Date:
Jan Wieck <janwieck@yahoo.com> writes:
>     I'm  about  99.666667% sure that the lock type choosen in the
>     FOR UPDATE case (line  511  of  parse_relation.c)  should  be
>     RowExclusiveLock  instead  of  RowShareLock.   Actually I get
>     "Deadlock risk" debug messages when selecting FOR UPDATE  and
>     then really UPDATE.

>     Should I change it?

Not sure, but if you do change it, that's *not* the only place.  I coded
that as RowShareLock because that was what was getting grabbed by the
executor for SELECT FOR UPDATE.  I believe the rewriter may need changed
as well, since it can also be the first grabber of a lock for a rel.

Note also that the docs say SELECT FOR UPDATE gets RowShareLock!

The "deadlock risk" message is not very bright, and I wouldn't suggest
changing the code just because of that.  I'm not even sure I want to
leave that check in the release version ...
        regards, tom lane


Re: Wrong FOR UPDATE lock type

From
Tom Lane
Date:
Jan Wieck <janwieck@Yahoo.com> writes:
>     Tom,
>     IIRC  the  "Deadlock risk" debug message is from you. I think
>     it must get a little smarter. IMHO an application that want's
>     to  UPDATE  something  in  a  transaction but must SELECT the
>     row(s) first to do it's own calculation on them,  should  use
>     SELECT FOR UPDATE. Is that debug output really appropriate in
>     this case (it raises from  RowShareLock  to  RowExclusiveLock
>     because  of  the  UPDATE  of the previous FOR UPDATE selected
>     row)?

Well, there is a theoretical chance of deadlock --- not against other
transactions doing the same thing, since RowShareLock and
RowExclusiveLock don't conflict, but you could construct deadlock
scenarios involving other transactions that grab ShareLock or
ShareRowExclusiveLock.  So I don't think it's appropriate for the
"deadlock risk" check to ignore RowShareLock->RowExclusiveLock
upgrades.

But I'm not sure the check should be enabled in production releases
anyway.  I just put it in as a quick and dirty debug check.  Perhaps
it should be under an #ifdef that's not enabled by default.
        regards, tom lane


RE: Wrong FOR UPDATE lock type

From
"Mikheev, Vadim"
Date:
> Well, there is a theoretical chance of deadlock --- not against other
> transactions doing the same thing, since RowShareLock and
> RowExclusiveLock don't conflict, but you could construct deadlock
> scenarios involving other transactions that grab ShareLock or
> ShareRowExclusiveLock.  So I don't think it's appropriate for the
> "deadlock risk" check to ignore RowShareLock->RowExclusiveLock
> upgrades.

There is theoretical chance of deadlock when two xactions lock
tables in different order and we can check this only in deadlock
detection code.

> But I'm not sure the check should be enabled in production releases
> anyway.  I just put it in as a quick and dirty debug check.  Perhaps
> it should be under an #ifdef that's not enabled by default.

No reason to learn users during transaction processing. We need in
good deadlock detection code and documentation.

Vadim