Re: [PATCH] LockAcquireExtended improvement - Mailing list pgsql-hackers

From Jingxian Li
Subject Re: [PATCH] LockAcquireExtended improvement
Date
Msg-id tencent_11D01D86DFF79B0A300BC1C7A4B6F0D9790A@qq.com
Whole thread Raw
In response to [PATCH] LockAcquireExtended improvement  ("Jingxian Li" <aqktjcm@qq.com>)
Responses Re: [PATCH] LockAcquireExtended improvement
List pgsql-hackers
Hi Andres, Thanks for your quick reply!

On 2023/11/29 0:51, Andres Freund wrote:
> Hi,
>
> On 2023-11-28 20:52:31 +0800, Jingxian Li wrote:
>> postgres=*# lock table test in exclusive mode ;
>>
>>
>> T4
>>
>> Case 1:
>>
>> postgres=*# lock table test in share row exclusive mode   nowait;
>>
>> ERROR:  could not   obtain lock on relation "test"
>>
>> --------------------------------------------
>>
>> Case 2:
>>
>> postgres=*# lock table test in share row exclusive mode;
>>
>> LOCK TABLE
>>
>>
>>
>> At T4 moment in session A, (case 1) when executing SQL “lock table test in share row exclusive mode nowait;”, an
erroroccurs with message “could not obtain lock on relation test";However, (case 2) when executing the SQL above
withoutnowait, lock can be obtained successfully. 
>>
>> Digging into the source code, I find that in case 2 the lock was obtained in
>> the function ProcSleep instead of LockAcquireExtended. Due to nowait logic
>> processed before WaitOnLock->ProcSleep, acquiring lock failed in case
>> 1. Can any changes be made so that the act of such lock granted occurs
>> before WaitOnLock?
> I don't think that'd make sense - lock reordering is done to prevent deadlocks
> and is quite expensive. Why should NOWAIT incur that cost?
>
>
>>
>> Providing a more universal case:
>>
>> Transaction A already holds an n-mode lock on table test. If then transaction A requests an m-mode lock on table
Test,m and n have the following constraints: 
>>
>> (lockMethodTable->conflictTab[n] & lockMethodTable->conflictTab[m]) == lockMethodTable->conflictTab[m]
>>
>> Obviously, in this case, m<=n.
>>
>> Should the m-mode lock be granted before WaitOnLock?
>>
>>
>> In the case of m=n (i.e. we already hold the lock), the m-mode lock is
>> immediately granted in the LocalLock path, without the need of lock conflict
>> check.
> Sure - it'd not help anybody to wait for a lock we already hold - in fact it'd
> create a lot of deadlocks.
>
>
>> Based on the facts above, can we obtain a weaker lock (m<n) on the same
>> object within the same transaction without doing lock conflict check?
> Perhaps. There's no inherent "lock strength" ordering for all locks though.



I also noticed that there is no inherent "lock strength" orderingfor all locks.
So I use the following method in the code to determine the strength of the lock:
if (m<n &&(lockMethodTable->conflictTab[n] &
lockMethodTable->conflictTab[m]) == lockMethodTable->conflictTab[m])
then we can say that m-mode lock is weaker than n-mode lock.


Transaction A already holds an n-mode lock on table test,
that is, there is no locks held conflicting with the n-mode lock on table test,
If then transaction A requests an m-mode lock on table test,
as n's confilctTab covers m, it can be concluded that
there are no locks conflicting with the requested m-mode lock.



>
> Greetings,
>
> Andres Freund
>

With regards,

Jingxian Li

pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: proposal: possibility to read dumped table's name from file
Next
From: Amit Kapila
Date:
Subject: Re: [PoC] pg_upgrade: allow to upgrade publisher node