diff options
author | Fujii Masao <fujii@postgresql.org> | 2024-10-25 00:18:32 +0900 |
---|---|---|
committer | Fujii Masao <fujii@postgresql.org> | 2024-10-25 00:18:32 +0900 |
commit | 86c30cef4a4cae951b2c30f1790fd5a7b81a2946 (patch) | |
tree | cc765705c2dea41ff8e7b9896bce3c2126e5101f | |
parent | 45188c2ea2391b7b24039e1632c726e2fc6b8008 (diff) | |
download | postgresql-86c30cef4a4cae951b2c30f1790fd5a7b81a2946.tar.gz postgresql-86c30cef4a4cae951b2c30f1790fd5a7b81a2946.zip |
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
-rw-r--r-- | src/backend/storage/lmgr/lock.c | 67 |
1 files changed, 39 insertions, 28 deletions
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 09a8ac15784..4fccb7277e1 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -3731,44 +3731,55 @@ GetLockStatusData(void) for (i = 0; i < ProcGlobal->allProcCount; ++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); - for (f = 0; f < FP_LOCK_SLOTS_PER_BACKEND; ++f) + for (uint32 g = 0; g < FastPathLockGroupsPerBackend; g++) { - LockInstanceData *instance; - uint32 lockbits = FAST_PATH_GET_BITS(proc, f); - - /* Skip unallocated slots. */ - if (!lockbits) + /* Skip groups without registered fast-path locks */ + if (proc->fpLockBits[g] == 0) continue; - if (el >= els) + for (int j = 0; j < FP_LOCK_SLOTS_PER_GROUP; j++) { - els += MaxBackends; - data->locks = (LockInstanceData *) - repalloc(data->locks, sizeof(LockInstanceData) * els); - } + LockInstanceData *instance; + uint32 f = FAST_PATH_SLOT(g, j); + uint32 lockbits = FAST_PATH_GET_BITS(proc, f); - 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; + /* Skip unallocated slots */ + if (!lockbits) + continue; - /* - * Successfully taking fast path lock means there were no - * conflicting locks. - */ - instance->waitStart = 0; + if (el >= els) + { + els += MaxBackends; + data->locks = (LockInstanceData *) + repalloc(data->locks, sizeof(LockInstanceData) * els); + } - 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) |