Refactor GetLockStatusData() to skip backends/groups without fast-path locks.
Previously, GetLockStatusData() checked all slots for every backend to gather fast-path lock data, which could be inefficient. This commit refactors it by skipping backends with PID=0 (since they don't hold fast-path locks) and skipping groups with no registered fast-path locks, improving efficiency. This refactoring is particularly beneficial, for example when max_connections and max_locks_per_transaction are set high, as it reduces unnecessary checks across numerous slots. Author: Fujii Masao Reviewed-by: Bertrand Drouvot Discussion: https://postgr.es/m/a0a00c44-31e9-4c67-9846-fb9636213ac9@oss.nttdata.com
This commit is contained in:
parent
45188c2ea2
commit
86c30cef4a
@ -3731,44 +3731,55 @@ GetLockStatusData(void)
|
|||||||
for (i = 0; i < ProcGlobal->allProcCount; ++i)
|
for (i = 0; i < ProcGlobal->allProcCount; ++i)
|
||||||
{
|
{
|
||||||
PGPROC *proc = &ProcGlobal->allProcs[i];
|
PGPROC *proc = &ProcGlobal->allProcs[i];
|
||||||
uint32 f;
|
|
||||||
|
/* Skip backends with pid=0, as they don't hold fast-path locks */
|
||||||
|
if (proc->pid == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
LWLockAcquire(&proc->fpInfoLock, LW_SHARED);
|
LWLockAcquire(&proc->fpInfoLock, LW_SHARED);
|
||||||
|
|
||||||
for (f = 0; f < FP_LOCK_SLOTS_PER_BACKEND; ++f)
|
for (uint32 g = 0; g < FastPathLockGroupsPerBackend; g++)
|
||||||
{
|
{
|
||||||
LockInstanceData *instance;
|
/* Skip groups without registered fast-path locks */
|
||||||
uint32 lockbits = FAST_PATH_GET_BITS(proc, f);
|
if (proc->fpLockBits[g] == 0)
|
||||||
|
|
||||||
/* Skip unallocated slots. */
|
|
||||||
if (!lockbits)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (el >= els)
|
for (int j = 0; j < FP_LOCK_SLOTS_PER_GROUP; j++)
|
||||||
{
|
{
|
||||||
els += MaxBackends;
|
LockInstanceData *instance;
|
||||||
data->locks = (LockInstanceData *)
|
uint32 f = FAST_PATH_SLOT(g, j);
|
||||||
repalloc(data->locks, sizeof(LockInstanceData) * els);
|
uint32 lockbits = FAST_PATH_GET_BITS(proc, f);
|
||||||
|
|
||||||
|
/* Skip unallocated slots */
|
||||||
|
if (!lockbits)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (el >= els)
|
||||||
|
{
|
||||||
|
els += MaxBackends;
|
||||||
|
data->locks = (LockInstanceData *)
|
||||||
|
repalloc(data->locks, sizeof(LockInstanceData) * els);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance = &data->locks[el];
|
||||||
|
SET_LOCKTAG_RELATION(instance->locktag, proc->databaseId,
|
||||||
|
proc->fpRelId[f]);
|
||||||
|
instance->holdMask = lockbits << FAST_PATH_LOCKNUMBER_OFFSET;
|
||||||
|
instance->waitLockMode = NoLock;
|
||||||
|
instance->vxid.procNumber = proc->vxid.procNumber;
|
||||||
|
instance->vxid.localTransactionId = proc->vxid.lxid;
|
||||||
|
instance->pid = proc->pid;
|
||||||
|
instance->leaderPid = proc->pid;
|
||||||
|
instance->fastpath = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Successfully taking fast path lock means there were no
|
||||||
|
* conflicting locks.
|
||||||
|
*/
|
||||||
|
instance->waitStart = 0;
|
||||||
|
|
||||||
|
el++;
|
||||||
}
|
}
|
||||||
|
|
||||||
instance = &data->locks[el];
|
|
||||||
SET_LOCKTAG_RELATION(instance->locktag, proc->databaseId,
|
|
||||||
proc->fpRelId[f]);
|
|
||||||
instance->holdMask = lockbits << FAST_PATH_LOCKNUMBER_OFFSET;
|
|
||||||
instance->waitLockMode = NoLock;
|
|
||||||
instance->vxid.procNumber = proc->vxid.procNumber;
|
|
||||||
instance->vxid.localTransactionId = proc->vxid.lxid;
|
|
||||||
instance->pid = proc->pid;
|
|
||||||
instance->leaderPid = proc->pid;
|
|
||||||
instance->fastpath = true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Successfully taking fast path lock means there were no
|
|
||||||
* conflicting locks.
|
|
||||||
*/
|
|
||||||
instance->waitStart = 0;
|
|
||||||
|
|
||||||
el++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proc->fpVXIDLock)
|
if (proc->fpVXIDLock)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user