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: 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->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
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 |