Re: [PATCH] LockAcquireExtended improvement

From: "Jingxian Li" <aqktjcm(at)qq(dot)com>
To: andres <andres(at)anarazel(dot)de>
Cc: "PostgreSQL Hackers" <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: [PATCH] LockAcquireExtended improvement
Date: 2023-11-30 03:43:19
Message-ID: tencent_11D01D86DFF79B0A300BC1C7A4B6F0D9790A@qq.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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: &nbsp;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 error occurs with message “could not obtain lock on relation test";However, (case 2) when executing the SQL above without nowait, 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-&gt;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-&gt;conflictTab[n] &amp; lockMethodTable-&gt;conflictTab[m]) == lockMethodTable-&gt;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

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Kapila 2023-11-30 03:52:40 Re: [PoC] pg_upgrade: allow to upgrade publisher node
Previous Message Tom Lane 2023-11-30 03:39:46 Re: proposal: possibility to read dumped table's name from file