Skip to content

Commit e80171d

Browse files
committed
Optimize iteration over PGPROC for fast-path lock searches.
This commit improves efficiency in FastPathTransferRelationLocks() and GetLockConflicts(), which iterate over PGPROCs to search for fast-path locks. Previously, these functions recalculated the fast-path group during every loop iteration, even though it remained constant. This update optimizes the process by calculating the group once and reusing it throughout the loop. The functions also now skip empty fast-path groups, avoiding unnecessary scans of their slots. Additionally, groups belonging to inactive backends (with pid=0) are always empty, so checking the group is sufficient to bypass these backends, further enhancing performance. Author: Fujii Masao <masao.fujii@gmail.com> Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Discussion: https://postgr.es/m/07d5fd6a-71f1-4ce8-8602-4cc6883f4bd1@oss.nttdata.com
1 parent a359d37 commit e80171d

File tree

1 file changed

+16
-12
lines changed
  • src/backend/storage/lmgr

1 file changed

+16
-12
lines changed

src/backend/storage/lmgr/lock.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,6 +2774,9 @@ FastPathTransferRelationLocks(LockMethod lockMethodTable, const LOCKTAG *locktag
27742774
Oid relid = locktag->locktag_field2;
27752775
uint32 i;
27762776

2777+
/* fast-path group the lock belongs to */
2778+
uint32 group = FAST_PATH_REL_GROUP(relid);
2779+
27772780
/*
27782781
* Every PGPROC that can potentially hold a fast-path lock is present in
27792782
* ProcGlobal->allProcs. Prepared transactions are not, but any
@@ -2783,8 +2786,7 @@ FastPathTransferRelationLocks(LockMethod lockMethodTable, const LOCKTAG *locktag
27832786
for (i = 0; i < ProcGlobal->allProcCount; i++)
27842787
{
27852788
PGPROC *proc = &ProcGlobal->allProcs[i];
2786-
uint32 j,
2787-
group;
2789+
uint32 j;
27882790

27892791
LWLockAcquire(&proc->fpInfoLock, LW_EXCLUSIVE);
27902792

@@ -2802,16 +2804,16 @@ FastPathTransferRelationLocks(LockMethod lockMethodTable, const LOCKTAG *locktag
28022804
* less clear that our backend is certain to have performed a memory
28032805
* fencing operation since the other backend set proc->databaseId. So
28042806
* for now, we test it after acquiring the LWLock just to be safe.
2807+
*
2808+
* Also skip groups without any registered fast-path locks.
28052809
*/
2806-
if (proc->databaseId != locktag->locktag_field1)
2810+
if (proc->databaseId != locktag->locktag_field1 ||
2811+
proc->fpLockBits[group] == 0)
28072812
{
28082813
LWLockRelease(&proc->fpInfoLock);
28092814
continue;
28102815
}
28112816

2812-
/* fast-path group the lock belongs to */
2813-
group = FAST_PATH_REL_GROUP(relid);
2814-
28152817
for (j = 0; j < FP_LOCK_SLOTS_PER_GROUP; j++)
28162818
{
28172819
uint32 lockmode;
@@ -3027,6 +3029,9 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
30273029
Oid relid = locktag->locktag_field2;
30283030
VirtualTransactionId vxid;
30293031

3032+
/* fast-path group the lock belongs to */
3033+
uint32 group = FAST_PATH_REL_GROUP(relid);
3034+
30303035
/*
30313036
* Iterate over relevant PGPROCs. Anything held by a prepared
30323037
* transaction will have been transferred to the primary lock table,
@@ -3040,8 +3045,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
30403045
for (i = 0; i < ProcGlobal->allProcCount; i++)
30413046
{
30423047
PGPROC *proc = &ProcGlobal->allProcs[i];
3043-
uint32 j,
3044-
group;
3048+
uint32 j;
30453049

30463050
/* A backend never blocks itself */
30473051
if (proc == MyProc)
@@ -3056,16 +3060,16 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
30563060
*
30573061
* See FastPathTransferRelationLocks() for discussion of why we do
30583062
* this test after acquiring the lock.
3063+
*
3064+
* Also skip groups without any registered fast-path locks.
30593065
*/
3060-
if (proc->databaseId != locktag->locktag_field1)
3066+
if (proc->databaseId != locktag->locktag_field1 ||
3067+
proc->fpLockBits[group] == 0)
30613068
{
30623069
LWLockRelease(&proc->fpInfoLock);
30633070
continue;
30643071
}
30653072

3066-
/* fast-path group the lock belongs to */
3067-
group = FAST_PATH_REL_GROUP(relid);
3068-
30693073
for (j = 0; j < FP_LOCK_SLOTS_PER_GROUP; j++)
30703074
{
30713075
uint32 lockmask;

0 commit comments

Comments
 (0)