On Tue, 28 Nov 2023 at 18:23, Jingxian Li <aqkt...@qq.com> wrote: > > 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.
I did not see any test added for this, should we add a test case for this? Regards, Vignesh