shrink_bloated_locallocktable_v2.patch
application/octet-stream
Filename: shrink_bloated_locallocktable_v2.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| src/backend/storage/lmgr/lock.c | 28 | 2 |
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index c895876..a85d792 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -254,6 +254,8 @@ static HTAB *LockMethodLockHash;
static HTAB *LockMethodProcLockHash;
static HTAB *LockMethodLocalHash;
+/* Initial size of LockMethodLocalHash table */
+#define LOCKMETHODLOCALHASH_INIT_SIZE 16
/* private state for error cleanup */
static LOCALLOCK *StrongLockInProgress;
@@ -339,6 +341,7 @@ PROCLOCK_PRINT(const char *where, const PROCLOCK *proclockP)
#endif /* not LOCK_DEBUG */
+static void CreateLocalLockHash(void);
static uint32 proclock_hash(const void *key, Size keysize);
static void RemoveLocalLock(LOCALLOCK *locallock);
static PROCLOCK *SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc,
@@ -431,6 +434,19 @@ InitLocks(void)
if (!found)
SpinLockInit(&FastPathStrongRelationLocks->mutex);
+ CreateLocalLockHash();
+}
+
+/*
+ * CreateLocalLockHash
+ * Create the LockMethodLocalHash hash table.
+ */
+static void
+CreateLocalLockHash(void)
+{
+ static HTAB *htab;
+ HASHCTL info;
+
/*
* Allocate non-shared hash table for LOCALLOCK structs. This stores lock
* counts and resource owner information.
@@ -447,12 +463,11 @@ InitLocks(void)
info.entrysize = sizeof(LOCALLOCK);
LockMethodLocalHash = hash_create("LOCALLOCK hash",
- 16,
+ LOCKMETHODLOCALHASH_INIT_SIZE,
&info,
HASH_ELEM | HASH_BLOBS);
}
-
/*
* Fetch the lock method table associated with a given lock
*/
@@ -2349,6 +2364,17 @@ LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
LWLockRelease(partitionLock);
} /* loop over partitions */
+ /*
+ * The hash_seq_search can become inefficient when the hash table has
+ * grown significantly larger than the default size due to the backend
+ * having run queries which obtained large numbers of locks at once. Here
+ * we'll build a new table at its initial size whenever the table is empty
+ * and has expanded from its original size.
+ */
+ if (status.curBucket > LOCKMETHODLOCALHASH_INIT_SIZE &&
+ hash_get_num_entries(LockMethodLocalHash) == 0)
+ CreateLocalLockHash();
+
#ifdef LOCK_DEBUG
if (*(lockMethodTable->trace_flag))
elog(LOG, "LockReleaseAll done");