On Fri, Nov 7, 2014 at 3:55 AM, Robert Haas <robertmh...@gmail.com> wrote: > > On Fri, Oct 31, 2014 at 9:07 AM, Andres Freund <and...@2ndquadrant.com> wrote: > > Maybe we can, as a first step, make those edges in the lock graph > > visible to the deadlock detector? It's pretty clear that undetected > > deadlocks aren't ok, but detectable deadlocks in a couple corner cases > > might be acceptable. > > An interesting point came to mind this morning on this topic, while > discussing this issue with Amit. Suppose process A1 holds a lock on > some object and process A2, a member of the same locking group, waits > for a lock on that same object. It follows that there must exist a > process B which either *holds* or *awaits* a lock which conflicts with > the one requested by A2; otherwise, A2 would have been granted the > lock at once. If B *holds* the conflicting lock, it may eventually > release it; but if B *awaits* the conflicting lock, we have a soft > deadlock, because A2 waits for B waits for A1, which we presume to > wait for A1.[1] > > The logical consequence of this is that, if a process seeks to acquire > a lock which is already held (in any mode) by a fellow group-member, > it had better jump over the entire wait queue and acquire the lock > immediately if no conflicting locks have already been granted. If it > fails to do this, it immediately creates a soft deadlock. What if > there *are* conflicting locks already granted? In that case, things > are more complicated. We could, for example, have this situation: A1 > holds AccessShareLock, B holds ExclusiveLock, C1 awaits ShareLock, and > then (following it in the wait queue) A2 awaits RowExclusiveLock. > This is not a deadlock, because B can finish, then C can get the lock, > then C1 can finish, then A2 can get the lock. But if C2 now waits for > some member of group A, then we have a soft deadlock between group A > and group C, which can be resolved by moving A2's request ahead of C1. > (This example is relatively realistic, too: a lock upgrade from > AccessShareLock to RowExclusiveLock is probably the most common type > of lock upgrade, for reasons that are hopefully obvious.) > > In practice, I suspect it's best to take a more aggressive approach > and have A2 jump straight to the head of the line right out of the > chute. Letting some parallel workers make progress while holding up > others out of a notion of locking fairness is probably stupid, because > they're probably dependent on each other in some way that makes it > useless for one to make progress while the others don't. For the same > reason, I'd argue that we ought to wait until all pending lock > requests from a given group can be satisfied before granting any of > them.
I think this logic can sometimes block processes from acquiring a lock which no one is holding. Assume Group-1 (G-1) is waiting on two locks (Lock L1 on Table T1 and Lock L2 on Table T2) which are held by unrelated processes P-2 and P-3 respectively; now P-3 releases the lock on table T-2 and cannot grant it to G-1 who is waiting on this lock because still L-1 lock cannot be granted to G-1. At this point the situation is that no one holds lock on T-2 and G-1 waits for it, however any new process won't be able to acquire lock on T-2 as there is already a waiter for the same in wait queue. OTOH if we would have granted lock for T-2 to G-1, it might have finished it's work and released the lock (considering it is a short time lock on catalog relation). If it is possible to have such a situation, then even though it is beneficial for certain cases to view several pending requests from a same group as single request, at the same time it can be harmful for some unrelated processes as well. With Regards, Amit Kapila. EnterpriseDB: http://www.enterprisedb.com