From 118cb90d4273f6cf84b98a4f9c9f66325bd827e2 Mon Sep 17 00:00:00 2001 From: Matthias van de Meent Date: Wed, 20 Nov 2024 17:31:26 +0100 Subject: [PATCH v0 4/4] Reduce PROCLOCK hash table size This reduces the memory usage of the heavyweight lock mechanism by 25%. Because the main LOCK table is already sized for max_locks_per_transaction for every backend, further allocation of more PROCLOCK entries doesn't make sense, as those would let the average number of locked objects per backend to increase past max_locks_per_transaction. --- src/backend/storage/lmgr/lock.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 15e1512e75..bd3e4d0f20 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -438,16 +438,18 @@ void LockManagerShmemInit(void) { HASHCTL info; - long init_table_size, - max_table_size; + long max_table_size; bool found; + Size allocated; + char *start; + char *end; + start = ShmemAllocNoError(0); /* * Compute init/max size to request for lock hashtables. Note these * calculations must agree with LockManagerShmemSize! */ max_table_size = NLOCKENTS(); - init_table_size = max_table_size / 2; /* * Allocate hash table for LOCK structs. This stores per-locked-object @@ -458,14 +460,17 @@ LockManagerShmemInit(void) info.num_partitions = NUM_LOCK_PARTITIONS; LockMethodLockHash = ShmemInitHash("LOCK hash", - init_table_size, + max_table_size, max_table_size, &info, HASH_ELEM | HASH_BLOBS | HASH_PARTITION); - /* Assume an average of 2 holders per lock */ - max_table_size *= 2; - init_table_size *= 2; + /* + * Assume every proc has max_locks_per_transaction locks. We don't + * need more PROCLOCK entries after that, because we can't acquire more + * locks after that. This is also more consistent with the advertised + * behaviour of max_locks_per_transaction. + */ /* * Allocate hash table for PROCLOCK structs. This stores @@ -477,7 +482,7 @@ LockManagerShmemInit(void) info.num_partitions = NUM_LOCK_PARTITIONS; LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash", - init_table_size, + max_table_size, max_table_size, &info, HASH_ELEM | HASH_FUNCTION | HASH_PARTITION); @@ -490,6 +495,13 @@ LockManagerShmemInit(void) sizeof(FastPathStrongRelationLockData), &found); if (!found) SpinLockInit(&FastPathStrongRelationLocks->mutex); + end = ShmemAllocNoError(0); + + allocated = end - start; + elog(LOG, "Lock ShMem: Allocated %lu for NLOCKENTS=%ld (= %d mlpxid * (%d m_c + %d m_p_xids))", + (unsigned long) allocated, max_table_size, + max_locks_per_xact, MaxBackends, max_prepared_xacts + ); } /* @@ -3682,7 +3694,6 @@ LockManagerShmemSize(void) size = add_size(size, hash_estimate_size(max_table_size, sizeof(LOCK))); /* proclock hash table */ - max_table_size *= 2; size = add_size(size, hash_estimate_size(max_table_size, sizeof(PROCLOCK))); /* -- 2.45.2