On Mon, May 27, 2019 at 2:01 AM Alex <zhihui.fan1...@gmail.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