Обсуждение: Order of granting with many waiting on one lock

Поиск
Список
Период
Сортировка

Order of granting with many waiting on one lock

От
Chris Angelico
Дата:
I've poked around a bit with my good friend Google Search and come up
blank, and I'm fairly sure this is something that shouldn't be relied
upon, but it's a point of curiosity.

Suppose I have twenty processes that all request the same lock. (I'm
working with pg_advisory_xact_lock, but any exclusive lock should do.)
One of them will obtain it, the others will block. The winner then
holds the lock for a second or so, then commits (releasing the lock),
then goes back and requests it again. Rinse and repeat. Yes, I know
this sounds ridiculous, but it's a simplified version of the
worst-case scenario in one of our systems.

The question is: How is it decided which process will get the lock
when the previous one commits? Is there any sort of guarantee that all
the processes will eventually get a turn, or could two processes
handball the lock to each other and play keepings-off against the
other eighteen?

Chris Angelico

Re: Order of granting with many waiting on one lock

От
Pavan Deolasee
Дата:
On Mon, Feb 11, 2013 at 12:26 PM, Chris Angelico <rosuav@gmail.com> wrote:
> Is there any sort of guarantee that all
> the processes will eventually get a turn, or could two processes
> handball the lock to each other and play keepings-off against the
> other eighteen?
>

That should not happen. There are instances when a lock requester will
be promoted ahead of others to avoid deadlock, but in the scenario you
described, no single process will starve forever. See following
comment in ProcSleep() function under src/backend/storage/lmgr/proc.c
which is self-explanatory.

/*
     * Determine where to add myself in the wait queue.
     *
     * Normally I should go at the end of the queue.  However, if I already
     * hold locks that conflict with the request of any previous waiter, put
     * myself in the queue just in front of the first such waiter. This is not
     * a necessary step, since deadlock detection would move me to before that
     * waiter anyway; but it's relatively cheap to detect such a conflict
     * immediately, and avoid delaying till deadlock timeout.
     *
     * Special case: if I find I should go in front of some waiter, check to
     * see if I conflict with already-held locks or the requests before that
     * waiter.  If not, then just grant myself the requested lock immediately.
     * This is the same as the test for immediate grant in LockAcquire, except
     * we are only considering the part of the wait queue before my insertion
     * point.
     */

Thanks,
Pavan

--
Pavan Deolasee
http://www.linkedin.com/in/pavandeolasee

Re: Order of granting with many waiting on one lock

От
Chris Angelico
Дата:
On Mon, Feb 11, 2013 at 6:12 PM, Pavan Deolasee
<pavan.deolasee@gmail.com> wrote:
>      * Determine where to add myself in the wait queue.
>      *
>      * Normally I should go at the end of the queue.

Ah! That's perfect. So they'll actually go into perfect strict
round-robin, assuming that there are no other locks coming into play
(which I expect will be the case; I've been careful to avoid
deadlocks).

Thanks Pavan, fast response and perfect information!

ChrisA