Re: some questions about fast-path-lock

From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: Alex <zhihui(dot)fan1213(at)gmail(dot)com>
Cc: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: some questions about fast-path-lock
Date: 2019-05-29 21:29:10
Message-ID: CA+TgmoYVjs9h=ZKK7bWXXt=UhXjyrNGxXoFx8X1VDhJ+JHVPOA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, May 27, 2019 at 2:01 AM Alex <zhihui(dot)fan1213(at)gmail(dot)com> wrote:
> I got some idea from the README under storage/lmgr and read some code of LockAcquireExtended , but I still have some questions now.
>
> LWLockAcquire(&MyProc->backendLock, LW_EXCLUSIVE);
> if (FastPathStrongRelationLocks->count[fasthashcode] != 0)
> acquired = false;
> else
> acquired = FastPathGrantRelationLock(locktag->locktag_field2,
> lockmode);
>
> 1. In the README, it says: "A key point of this algorithm is that it must be possible to verify the
> absence of possibly conflicting locks without fighting over a shared LWLock or
> spinlock. Otherwise, this effort would simply move the contention bottleneck
> from one place to another."
>
> but in the code, there is LWLockAcquire in the above code. Actually I can't think out how can we proceed without a lock.

The per-backend lock is not heavily contended, because under normal
circumstances it is only accessed by a single backend. If there is a
potential lock conflict that must be analyzed then another backend may
acquire it and that might lead to a little bit of contention, but it
happens quite rarely -- so the overall contention is still much less
than if everyone is fighting over the lock manager partition locks.

> 2. Why does the MyProc->backendLock work? it is MyProc not a global lock.

It's still an LWLock. Putting it inside of MyProc doesn't make it
magically stop working. MyProc is in shared memory, not backend-local
memory, if that's what you are confused about.

> 3. for the line, acquired = FastPathGrantRelationLock(locktag->locktag_field2,
> lockmode); I think it should be able to replaced with "acquired = true" (but obviously I'm wrong) . I read "FastPathGrantRelationLock" but can't understand it.

It can't say 'acquired = true' because each backend can only acquire a
maximum of 16 relation locks via the fast-path mechanism. If a
process acquires more than 16 relation locks, at least some of them
will have to be acquired without benefit of the fast-path. This value
could be changed by changing the value of the constant
FP_LOCK_SLOTS_PER_BACKEND, but since we scan the array linearly,
making it too big will lead to other problems. I don't quite
understand what about FastPathGrantRelationLock you don't understand -
it's a pretty straightforwardly-coded search for either (a) an
existing fastpath slot for the specified relid or failing that (b) an
unused fastpath slot.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2019-05-29 21:32:45 Re: message style
Previous Message Robert Haas 2019-05-29 21:23:14 Re: Names