Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit15ef6ff

Browse files
author
Amit Kapila
committed
Assert that we don't acquire a heavyweight lock on another object after
relation extension lock.The only exception to the rule is that we can try to acquire the samerelation extension lock more than once. This is allowed as we are notcreating any new lock for this case. This restriction implies that therelation extension lock won't ever participate in the deadlock cyclebecause we can never wait for any other heavyweight lock after acquiringthis lock.Such a restriction is okay for relation extension locks as unlike otherheavyweight locks these are not held till the transaction end. These aretaken for a short duration to extend a particular relation and thenreleased.Author: Dilip Kumar, with few changes by Amit KapilaReviewed-by: Amit Kapila, Kuntal Ghosh and Sawada MasahikoDiscussion:https://postgr.es/m/CAD21AoCmT3cFQUN4aVvzy5chw7DuzXrJCbrjTU05B+Ss=Gn1LA@mail.gmail.com
1 parentb897b3a commit15ef6ff

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

‎src/backend/storage/lmgr/lock.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,21 @@ typedef struct TwoPhaseLockRecord
170170
*/
171171
staticintFastPathLocalUseCount=0;
172172

173+
/*
174+
* Flag to indicate if the relation extension lock is held by this backend.
175+
* This flag is used to ensure that while holding the relation extension lock
176+
* we don't try to acquire a heavyweight lock on any other object. This
177+
* restriction implies that the relation extension lock won't ever participate
178+
* in the deadlock cycle because we can never wait for any other heavyweight
179+
* lock after acquiring this lock.
180+
*
181+
* Such a restriction is okay for relation extension locks as unlike other
182+
* heavyweight locks these are not held till the transaction end. These are
183+
* taken for a short duration to extend a particular relation and then
184+
* released.
185+
*/
186+
staticboolIsRelationExtensionLockHeldPG_USED_FOR_ASSERTS_ONLY= false;
187+
173188
/* Macros for manipulating proc->fpLockBits */
174189
#defineFAST_PATH_BITS_PER_SLOT3
175190
#defineFAST_PATH_LOCKNUMBER_OFFSET1
@@ -840,6 +855,13 @@ LockAcquireExtended(const LOCKTAG *locktag,
840855
returnLOCKACQUIRE_ALREADY_HELD;
841856
}
842857

858+
/*
859+
* We don't acquire any other heavyweight lock while holding the relation
860+
* extension lock. We do allow to acquire the same relation extension
861+
* lock more than once but that case won't reach here.
862+
*/
863+
Assert(!IsRelationExtensionLockHeld);
864+
843865
/*
844866
* Prepare to emit a WAL record if acquisition of this lock needs to be
845867
* replayed in a standby server.
@@ -1287,6 +1309,23 @@ SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
12871309
returnproclock;
12881310
}
12891311

1312+
/*
1313+
* Check and set/reset the flag that we hold the relation extension lock.
1314+
*
1315+
* It is callers responsibility that this function is called after
1316+
* acquiring/releasing the relation extension lock.
1317+
*
1318+
* Pass acquired as true if lock is acquired, false otherwise.
1319+
*/
1320+
staticinlinevoid
1321+
CheckAndSetLockHeld(LOCALLOCK*locallock,boolacquired)
1322+
{
1323+
#ifdefUSE_ASSERT_CHECKING
1324+
if (LOCALLOCK_LOCKTAG(*locallock)==LOCKTAG_RELATION_EXTEND)
1325+
IsRelationExtensionLockHeld=acquired;
1326+
#endif
1327+
}
1328+
12901329
/*
12911330
* Subroutine to free a locallock entry
12921331
*/
@@ -1322,6 +1361,11 @@ RemoveLocalLock(LOCALLOCK *locallock)
13221361
(void*)&(locallock->tag),
13231362
HASH_REMOVE,NULL))
13241363
elog(WARNING,"locallock table corrupted");
1364+
1365+
/*
1366+
* Indicate that the lock is released for certain types of locks
1367+
*/
1368+
CheckAndSetLockHeld(locallock, false);
13251369
}
13261370

13271371
/*
@@ -1618,6 +1662,9 @@ GrantLockLocal(LOCALLOCK *locallock, ResourceOwner owner)
16181662
locallock->numLockOwners++;
16191663
if (owner!=NULL)
16201664
ResourceOwnerRememberLock(owner,locallock);
1665+
1666+
/* Indicate that the lock is acquired for certain types of locks. */
1667+
CheckAndSetLockHeld(locallock, true);
16211668
}
16221669

16231670
/*

‎src/include/storage/lock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ typedef struct LOCALLOCK
419419
}LOCALLOCK;
420420

421421
#defineLOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)
422+
#defineLOCALLOCK_LOCKTAG(llock) ((LockTagType) (llock).tag.lock.locktag_type)
422423

423424

424425
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp