v0-0004-Reduce-PROCLOCK-hash-table-size.patch
application/octet-stream
Filename: v0-0004-Reduce-PROCLOCK-hash-table-size.patch
Type: application/octet-stream
Part: 3
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v0-0004
Subject: Reduce PROCLOCK hash table size
| File | + | − |
|---|---|---|
| src/backend/storage/lmgr/lock.c | 20 | 9 |
From 118cb90d4273f6cf84b98a4f9c9f66325bd827e2 Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
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