From 98dd50a2f70600a799d6d5827d48ddb4fb09fdb7 Mon Sep 17 00:00:00 2001 From: Dilip Kumar Date: Fri, 13 Mar 2020 14:02:06 +0530 Subject: [PATCH v6 2/4] Extend the assert for the page lock --- src/backend/storage/lmgr/lock.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 24ca900..e182ec7 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -171,13 +171,16 @@ typedef struct TwoPhaseLockRecord static int FastPathLocalUseCount = 0; /* - * Flag is set if the relation extension lock is currently held by this backend. - * We need this flag so that we can ensure that while holding the relation - * extension lock we are not trying to acquire any other heavy weight lock. - * Basically, that will ensuring that the proc holding relation extension lock - * can not wait for any another lock which can lead to a deadlock. + * Flag is set if the relation extension/page lock is currently held by this + * backend. We need this flag so that we can ensure that while holding the + * relation extension/page lock we are not trying to acquire any other heavy + * weight lock. Basically, that will ensuring that the proc holding relation + * extension lock can not wait for any another lock which can lead to a + * deadlock. However, for page lock the exception is that while holding the + * page lock it can wait on the relation extension lock. */ static bool IsRelationExtensionLockHeld = false; +static bool IsPageLockHeld = false; /* Macros for manipulating proc->fpLockBits */ #define FAST_PATH_BITS_PER_SLOT 3 @@ -854,11 +857,17 @@ LockAcquireExtended(const LOCKTAG *locktag, /* * We should not try to acquire any other heavyweight lock if we are already - * holding the relation extension lock. If we are trying to hold the same - * relation extension lock then it should have been already granted so we - * will not come here. + * holding the relation extension/page lock. If we are trying to hold the + * same relation extension lock then it should have been already granted so + * we will not come here. However, While holding the page lock we don't + * need to ensure that whether we are trying to acquire the relation + * extension lock on the same relation or any other relation because we are + * already ensuring that after holding the relation extension lock we are + * not going to wait for any other lock. */ - Assert(!IsRelationExtensionLockHeld); + Assert(!IsRelationExtensionLockHeld && + (!IsPageLockHeld || + (locktag->locktag_type == LOCKTAG_RELATION_EXTEND))); /* * Prepare to emit a WAL record if acquisition of this lock needs to be @@ -1308,25 +1317,29 @@ SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc, } /* - * CheckAndSetLockHeld -- check and set the flag that we hold relation extension - * lock. + * CheckAndSetLockHeld -- check and set the flag that we hold relation + * extension/page lock. */ static inline void CheckAndSetLockHeld(LOCALLOCK *locallock) { if (LOCALLOCK_LOCKTAG(*locallock) == LOCKTAG_RELATION_EXTEND) IsRelationExtensionLockHeld = true; + else if (LOCALLOCK_LOCKTAG(*locallock) == LOCKTAG_PAGE) + IsPageLockHeld = true; } /* * CheckAndReSetLockHeld -- check and reset the flag if we have released the - * relation extension lock. + * relation extension/page lock. */ static inline void CheckAndReSetLockHeld(LOCALLOCK *locallock) { if (LOCALLOCK_LOCKTAG(*locallock) == LOCKTAG_RELATION_EXTEND) IsRelationExtensionLockHeld = false; + else if (LOCALLOCK_LOCKTAG(*locallock) == LOCKTAG_PAGE) + IsPageLockHeld = false; } /* @@ -1365,7 +1378,7 @@ RemoveLocalLock(LOCALLOCK *locallock) HASH_REMOVE, NULL)) elog(WARNING, "locallock table corrupted"); - /* Check and reset the lock held flag. */ + /* Check and reset the lock held flags. */ CheckAndReSetLockHeld(locallock); } @@ -1664,7 +1677,7 @@ GrantLockLocal(LOCALLOCK *locallock, ResourceOwner owner) if (owner != NULL) ResourceOwnerRememberLock(owner, locallock); - /* Set the flag if we have acquired relation extension lock. */ + /* Check and set the lock held flags. */ CheckAndSetLockHeld(locallock); } -- 1.8.3.1