From 39432cfb614cc1996979bbeb22d4d0df631aca90 Mon Sep 17 00:00:00 2001 From: Mahendra Singh Thalor Date: Tue, 3 Mar 2020 04:03:45 -0800 Subject: [PATCH 2/2] Added assert to verify that we never try to take any heavy weight lock after acquiring relation Extension lock In LockAcquireExtended, we will call AssertAnyExtentionLockHeadByMe to check that our backend is not holding any extention lock. --- src/backend/storage/lmgr/lock.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index ef14655cf8..b04235f3f2 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -339,6 +339,7 @@ PROCLOCK_PRINT(const char *where, const PROCLOCK *proclockP) #endif /* not LOCK_DEBUG */ +static void AssertAnyExtentionLockHeadByMe(void); static uint32 proclock_hash(const void *key, Size keysize); static void RemoveLocalLock(LOCALLOCK *locallock); static PROCLOCK *SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc, @@ -587,6 +588,31 @@ LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode) return (locallock && locallock->nLocks > 0); } +/* + * AssertAnyExtentionLockHeadByMe -- test whether any EXTENSION lock held by + * this backend. If any EXTENSION lock is hold by this backend, then assert + * will fail. To use this function, assert should be enabled. + */ +void AssertAnyExtentionLockHeadByMe() +{ +#ifdef USE_ASSERT_CHECKING + HASH_SEQ_STATUS scan_status; + LOCALLOCK *locallock; + + hash_seq_init(&scan_status, LockMethodLocalHash); + while ((locallock = (LOCALLOCK *) hash_seq_search(&scan_status)) != NULL) + { + /* + * Either lock is other than extension or we should not held extension + * lock. Because after acquiring extension lock, we should never try + * to acquire any lock. + */ + Assert (locallock->tag.lock.locktag_type != LOCKTAG_RELATION_EXTEND || + locallock->nLocks == 0); + } +#endif +} + /* * LockHasWaiters -- look up 'locktag' and check if releasing this * lock would wake up other processes waiting for it. @@ -749,6 +775,12 @@ LockAcquireExtended(const LOCKTAG *locktag, bool found_conflict; bool log_lock = false; + /* + * This backend should not hold any relation extension lock while acquiring + * heavy weight lock. + */ + AssertAnyExtentionLockHeadByMe(); + if (lockmethodid <= 0 || lockmethodid >= lengthof(LockMethods)) elog(ERROR, "unrecognized lock method: %d", lockmethodid); lockMethodTable = LockMethods[lockmethodid]; -- 2.17.1