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 T2 postgres=# begin; BEGIN postgres=*# lock table test in access exclusive mode ; LOCK TABLE T3 postgres=# begin; BEGIN 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? 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. 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. I am attaching a patch here with which the problem in case 1 fixed.
With Regards, Jingxian Li.
v1-0001-LockAcquireExtended-improvement.patch
Description: Binary data