[PATCH] LockAcquireExtended improvement

From: Jingxian Li <aqktjcm(at)qq(dot)com>
To: PostgreSQL&nbsp;Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: [PATCH] LockAcquireExtended improvement
Date: 2023-11-28 12:52:31
Message-ID: tencent_3912DE2F359F4FD003E110EF7EC4748A1905@qq.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi hackers,

I found a problem when doing the test shown below:

Time

Session A

Session B


T1

postgres=# create table test(a int);

CREATE TABLE

postgres=# insert into test values (1);

INSERT 0 1

&nbsp;


T2

postgres=# begin;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

BEGIN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

postgres=*# lock table test in access exclusive mode ;

LOCK TABLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;


T3

&nbsp;

postgres=# begin;

BEGIN

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"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

--------------------------------------------

Case 2:

postgres=*# lock table test in share row exclusive mode;

LOCK TABLE

&nbsp;


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?

&nbsp;

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?

&nbsp;

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.

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?

Since m=n works, m<n should certainly work too.

&nbsp;

I am attaching a patch here with which the problem in case 1 fixed.

With&nbsp;Regards,
Jingxian Li.

&nbsp;

Attachment Content-Type Size
v1-0001-LockAcquireExtended-improvement.patch application/octet-stream 4.1 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Heikki Linnakangas 2023-11-28 13:06:06 Re: Streaming I/O, vectored I/O (WIP)
Previous Message Robert Haas 2023-11-28 12:52:02 Re: POC, WIP: OR-clause support for indexes