Soft deadlocks

Started by Gregory Starkover 18 years ago2 messages
#1Gregory Stark
stark@enterprisedb.com

I'm trying to understand what a soft deadlock is as described by deadlock.c.

As best I understand if a process, A, is waiting for a lock and is being
blocked only because someone, B, is ahead of it in the queue but hasn't been
granted the conflicting lock we want to jump A ahead of B.

So if i do something like:

process X:
---------
select * from x where i=1 for share;

----------------

process B:
---------
select * from x where i=1 for update;

----------------

process A:
---------
select * from x where i=1 for share;

process A will block, but when the deadlock timeout fires it should get jumped
ahead of process B.

If that's right then, uh, it doesn't seem to be working.

Process B:

postgres=# select * from x where i = 0 for update;
LOG: process 4629 still waiting for ShareLock on transaction 7802 after 5000.149 ms

Process A:

postgres=# select * from x where i = 0 for share;
LOG: process 4631 still waiting for ShareLock on tuple (0,1) of relation 16423 of database 11408 after 5000.151 ms

--
Gregory Stark
EnterpriseDB http://www.enterprisedb.com

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gregory Stark (#1)
Re: Soft deadlocks

Gregory Stark <stark@enterprisedb.com> writes:

I'm trying to understand what a soft deadlock is as described by deadlock.c.

As best I understand if a process, A, is waiting for a lock and is being
blocked only because someone, B, is ahead of it in the queue but hasn't been
granted the conflicting lock we want to jump A ahead of B.

No, we only do that if it breaks a deadlock. In your example there is
no reason to move process A ahead of B.

A more typical situation is like this:

Process A:
begin;
select * from T where ...;
-- now A holds AccessShareLock on T

Process B:
lock table T;
-- wants AccessExclusiveLock on T, blocks waiting for A

Process A:
lock table T;
-- blocks behind B?

Fairness would normally demand that A queue behind B for the
AccessExclusiveLock, but if we do that we have a deadlock.
So we spring A ahead of B and let it have the AccessExclusiveLock
out of turn.

This is just the base case; you can get into similar situations
involving more than one lockable object and more than two processes.
I believe that the above case is caught by the test in ProcSleep and
A will be granted the lock upgrade without blocking at all; but any
more-complex situation will only be discovered when someone runs the
deadlock checker.

regards, tom lane