diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 1337eab..5f72541 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -114,10 +114,12 @@
 #include "postmaster/postmaster.h"
 #include "postmaster/syslogger.h"
 #include "replication/walsender.h"
+#include "storage/buf_internals.h"
 #include "storage/fd.h"
 #include "storage/ipc.h"
 #include "storage/pg_shmem.h"
 #include "storage/pmsignal.h"
+#include "storage/predicate.h"
 #include "storage/proc.h"
 #include "tcop/tcopprot.h"
 #include "utils/builtins.h"
@@ -487,6 +489,9 @@ typedef struct
 #endif
 	int			NamedLWLockTrancheRequests;
 	NamedLWLockTranche *NamedLWLockTrancheArray;
+	LWLockPadded *BufferMappingLWLockArray;
+	LWLockPadded *LockHashLWLockArray;
+	LWLockPadded *PredicateLockHashLWLockArray;
 	LWLockPadded *MainLWLockArray;
 	slock_t    *ProcStructLock;
 	PROC_HDR   *ProcGlobal;
@@ -5807,6 +5812,9 @@ save_backend_variables(BackendParameters *param, Port *port,
 #endif
 	param->NamedLWLockTrancheRequests = NamedLWLockTrancheRequests;
 	param->NamedLWLockTrancheArray = NamedLWLockTrancheArray;
+	param->BufferMappingLWLockArray = BufferMappingLWLockArray;
+	param->LockHashLWLockArray = LockHashLWLockArray;
+	param->PredicateLockHashLWLockArray = PredicateLockHashLWLockArray;
 	param->MainLWLockArray = MainLWLockArray;
 	param->ProcStructLock = ProcStructLock;
 	param->ProcGlobal = ProcGlobal;
@@ -6040,6 +6048,9 @@ restore_backend_variables(BackendParameters *param, Port *port)
 #endif
 	NamedLWLockTrancheRequests = param->NamedLWLockTrancheRequests;
 	NamedLWLockTrancheArray = param->NamedLWLockTrancheArray;
+	BufferMappingLWLockArray = param->BufferMappingLWLockArray;
+	LockHashLWLockArray = param->LockHashLWLockArray;
+	PredicateLockHashLWLockArray = param->PredicateLockHashLWLockArray;
 	MainLWLockArray = param->MainLWLockArray;
 	ProcStructLock = param->ProcStructLock;
 	ProcGlobal = param->ProcGlobal;
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index b423aa7..ee0839c 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -14,6 +14,7 @@
  */
 #include "postgres.h"
 
+#include "miscadmin.h"
 #include "storage/bufmgr.h"
 #include "storage/buf_internals.h"
 
@@ -23,6 +24,7 @@ char	   *BufferBlocks;
 LWLockMinimallyPadded *BufferIOLWLockArray = NULL;
 LWLockTranche BufferIOLWLockTranche;
 LWLockTranche BufferContentLWLockTranche;
+LWLockPadded *BufferMappingLWLockArray = NULL;
 
 
 /*
@@ -147,6 +149,10 @@ InitBufferPool(void)
 		GetBufferDescriptor(NBuffers - 1)->freeNext = FREENEXT_END_OF_LIST;
 	}
 
+	/* Get LWLocks for buffer mapping table */
+	if (!IsUnderPostmaster)
+		BufferMappingLWLockArray = GetNamedLWLockTranche("Buffer Mapping Locks");
+
 	/* Init other shared buffer-management stuff */
 	StrategyInitialize(!foundDescs);
 }
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 36a04fc..eaf9069 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -94,6 +94,12 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
 {
 	PGShmemHeader *shim = NULL;
 
+	/*
+	 * Ask for named tranches before creation of shared memory.
+	 */
+	if (!IsUnderPostmaster)
+		RequestNamedTranches();
+
 	if (!IsUnderPostmaster)
 	{
 		PGShmemHeader *seghdr;
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index e3e9599..19f3f2e 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -55,6 +55,8 @@ int			max_locks_per_xact; /* set by guc.c */
 #define NLOCKENTS() \
 	mul_size(max_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
 
+LWLockPadded *LockHashLWLockArray = NULL;
+
 
 /*
  * Data structures defining the semantics of the standard lock methods.
@@ -447,6 +449,10 @@ InitLocks(void)
 									  16,
 									  &info,
 									  HASH_ELEM | HASH_BLOBS);
+
+	/* Get LWLocks for lockmgr's shared hash tables */
+	if (!IsUnderPostmaster)
+		LockHashLWLockArray = GetNamedLWLockTranche("Lock Hash Locks");
 }
 
 
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 5c68473..b440bb6 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -91,7 +91,7 @@
 #endif
 
 
-/* We use the ShmemLock spinlock to protect LWLockAssign */
+/* We use the ShmemLock spinlock to protect LWLockCounter */
 extern slock_t *ShmemLock;
 
 #define LW_FLAG_HAS_WAITERS			((uint32) 1 << 30)
@@ -364,30 +364,6 @@ NumLWLocksByNamedTranches(void)
 }
 
 /*
- * Compute number of LWLocks to allocate in the main array.
- */
-static int
-NumLWLocks(void)
-{
-	int			numLocks;
-
-	/*
-	 * Many users of LWLocks no longer reserve space in the main array here,
-	 * but instead allocate separate tranches.  The latter approach has the
-	 * advantage of allowing LWLOCK_STATS and LOCK_DEBUG output to produce
-	 * more useful output.
-	 */
-
-	/* Predefined LWLocks */
-	numLocks = NUM_FIXED_LWLOCKS;
-
-	/* Disallow named LWLocks' requests after startup */
-	lock_named_request_allowed = false;
-
-	return numLocks;
-}
-
-/*
  * Compute shmem space needed for LWLocks and named tranches.
  */
 Size
@@ -395,7 +371,7 @@ LWLockShmemSize(void)
 {
 	Size		size;
 	int			i;
-	int			numLocks = NumLWLocks();
+	int			numLocks = NUM_INDIVIDUAL_LWLOCKS;
 
 	numLocks += NumLWLocksByNamedTranches();
 
@@ -403,7 +379,7 @@ LWLockShmemSize(void)
 	size = mul_size(numLocks, sizeof(LWLockPadded));
 
 	/* Space for dynamic allocation counter, plus room for alignment. */
-	size = add_size(size, 3 * sizeof(int) + LWLOCK_PADDED_SIZE);
+	size = add_size(size, sizeof(int) + LWLOCK_PADDED_SIZE);
 
 	/* space for named tranches. */
 	size = add_size(size, mul_size(NamedLWLockTrancheRequests, sizeof(NamedLWLockTranche)));
@@ -412,6 +388,9 @@ LWLockShmemSize(void)
 	for (i = 0; i < NamedLWLockTrancheRequests; i++)
 		size = add_size(size, strlen(NamedLWLockTrancheRequestArray[i].tranche_name) + 1);
 
+	/* Disallow named LWLocks' requests after startup */
+	lock_named_request_allowed = false;
+
 	return size;
 }
 
@@ -433,7 +412,7 @@ CreateLWLocks(void)
 
 	if (!IsUnderPostmaster)
 	{
-		int			numLocks = NumLWLocks();
+		int			numLocks = NUM_INDIVIDUAL_LWLOCKS;
 		int			numNamedLocks = NumLWLocksByNamedTranches();
 		Size		spaceLocks = LWLockShmemSize();
 		LWLockPadded *lock;
@@ -445,8 +424,8 @@ CreateLWLocks(void)
 		/* Allocate space */
 		ptr = (char *) ShmemAlloc(spaceLocks);
 
-		/* Leave room for dynamic allocation of locks and tranches */
-		ptr += 3 * sizeof(int);
+		/* Leave room for dynamic allocation of tranches */
+		ptr += sizeof(int);
 
 		/* Ensure desired alignment of LWLock array */
 		ptr += LWLOCK_PADDED_SIZE - ((uintptr_t) ptr) % LWLOCK_PADDED_SIZE;
@@ -458,16 +437,11 @@ CreateLWLocks(void)
 			LWLockInitialize(&lock->lock, LWTRANCHE_MAIN);
 
 		/*
-		 * Initialize the dynamic-allocation counters, which are stored just
-		 * before the first LWLock.  LWLockCounter[0] is the allocation
-		 * counter for lwlocks, LWLockCounter[1] is the maximum number that
-		 * can be allocated from the main array, and LWLockCounter[2] is the
-		 * allocation counter for tranches.
+		 * Initialize the dynamic-allocation counter for tranches, which is
+		 * stored just before the first LWLock.
 		 */
-		LWLockCounter = (int *) ((char *) MainLWLockArray - 3 * sizeof(int));
-		LWLockCounter[0] = NUM_FIXED_LWLOCKS;
-		LWLockCounter[1] = numLocks;
-		LWLockCounter[2] = LWTRANCHE_FIRST_USER_DEFINED;
+		LWLockCounter = (int *) ((char *) MainLWLockArray - sizeof(int));
+		*LWLockCounter = LWTRANCHE_FIRST_USER_DEFINED;
 
 		/* Initialize named tranches. */
 		if (NamedLWLockTrancheRequests > 0)
@@ -536,32 +510,6 @@ InitLWLockAccess(void)
 }
 
 /*
- * LWLockAssign - assign a dynamically-allocated LWLock number
- *
- * We interlock this using the same spinlock that is used to protect
- * ShmemAlloc().  Interlocking is not really necessary during postmaster
- * startup, but it is needed if any user-defined code tries to allocate
- * LWLocks after startup.
- */
-LWLock *
-LWLockAssign(void)
-{
-	LWLock	   *result;
-	int		   *LWLockCounter;
-
-	LWLockCounter = (int *) ((char *) MainLWLockArray - 3 * sizeof(int));
-	SpinLockAcquire(ShmemLock);
-	if (LWLockCounter[0] >= LWLockCounter[1])
-	{
-		SpinLockRelease(ShmemLock);
-		elog(ERROR, "no more LWLocks available");
-	}
-	result = &MainLWLockArray[LWLockCounter[0]++].lock;
-	SpinLockRelease(ShmemLock);
-	return result;
-}
-
-/*
  * GetNamedLWLockTranche - returns the base address of LWLock from the
  *		specified tranche.
  *
@@ -574,16 +522,13 @@ GetNamedLWLockTranche(const char *tranche_name)
 {
 	int			lock_pos;
 	int			i;
-	int		   *LWLockCounter;
-
-	LWLockCounter = (int *) ((char *) MainLWLockArray - 3 * sizeof(int));
 
 	/*
 	 * Obtain the position of base address of LWLock belonging to requested
 	 * tranche_name in MainLWLockArray.  LWLocks for named tranches are placed
-	 * in MainLWLockArray after LWLocks specified by LWLockCounter[1].
+	 * in MainLWLockArray after individual LWLocks.
 	 */
-	lock_pos = LWLockCounter[1];
+	lock_pos = NUM_INDIVIDUAL_LWLOCKS;
 	for (i = 0; i < NamedLWLockTrancheRequests; i++)
 	{
 		if (strcmp(NamedLWLockTrancheRequestArray[i].tranche_name,
@@ -609,9 +554,9 @@ LWLockNewTrancheId(void)
 	int			result;
 	int		   *LWLockCounter;
 
-	LWLockCounter = (int *) ((char *) MainLWLockArray - 3 * sizeof(int));
+	LWLockCounter = (int *) ((char *) MainLWLockArray - sizeof(int));
 	SpinLockAcquire(ShmemLock);
-	result = LWLockCounter[2]++;
+	result = (*LWLockCounter)++;
 	SpinLockRelease(ShmemLock);
 
 	return result;
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index 026d2b9..04ad709 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -232,6 +232,8 @@
 	 && (GET_PREDICATELOCKTARGETTAG_DB(covered_target) ==	 /* (1) */	\
 		 GET_PREDICATELOCKTARGETTAG_DB(covering_target)))
 
+LWLockPadded *PredicateLockHashLWLockArray = NULL;
+
 /*
  * The predicate locking target and lock shared hash tables are partitioned to
  * reduce contention.  To determine which partition a given target belongs to,
@@ -242,10 +244,9 @@
 #define PredicateLockHashPartition(hashcode) \
 	((hashcode) % NUM_PREDICATELOCK_PARTITIONS)
 #define PredicateLockHashPartitionLock(hashcode) \
-	(&MainLWLockArray[PREDICATELOCK_MANAGER_LWLOCK_OFFSET + \
-		PredicateLockHashPartition(hashcode)].lock)
+	(&PredicateLockHashLWLockArray[PredicateLockHashPartition(hashcode)].lock)
 #define PredicateLockHashPartitionLockByIndex(i) \
-	(&MainLWLockArray[PREDICATELOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
+	(&PredicateLockHashLWLockArray[i].lock)
 
 #define NPREDICATELOCKTARGETENTS() \
 	mul_size(max_predicate_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
@@ -1290,6 +1291,10 @@ InitPredicateLocks(void)
 	/* Pre-calculate the hash and partition lock of the scratch entry */
 	ScratchTargetTagHash = PredicateLockTargetTagHashCode(&ScratchTargetTag);
 	ScratchPartitionLock = PredicateLockHashPartitionLock(ScratchTargetTagHash);
+
+	/* Get LWLocks for predicate lock shared hash table */
+	if (!IsUnderPostmaster)
+		PredicateLockHashLWLockArray = GetNamedLWLockTranche("Predicate Lock Hash Locks");
 }
 
 /*
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 03cbb6e..7423b8f 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -1315,6 +1315,16 @@ RecheckDataDirLockFile(void)
 	return false;
 }
 
+/*
+ * Request named tranches for various chunks of lwlocks.
+ */
+void
+RequestNamedTranches(void)
+{
+	RequestNamedLWLockTranche("Buffer Mapping Locks", NUM_BUFFER_PARTITIONS);
+	RequestNamedLWLockTranche("Lock Hash Locks", NUM_LOCK_PARTITIONS);
+	RequestNamedLWLockTranche("Predicate Lock Hash Locks", NUM_PREDICATELOCK_PARTITIONS);
+}
 
 /*-------------------------------------------------------------------------
  *				Version checking support
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index ec535a3..6034f0b 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -321,6 +321,8 @@ extern void ChangeToDataDir(void);
 extern void SwitchToSharedLatch(void);
 extern void SwitchBackToLocalLatch(void);
 
+extern void RequestNamedTranches(void);
+
 /* in utils/misc/superuser.c */
 extern bool superuser(void);	/* current user is superuser */
 extern bool superuser_arg(Oid roleid);	/* given user is superuser */
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index cbc4843..8ad2ea3 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -104,10 +104,9 @@ typedef struct buftag
 #define BufTableHashPartition(hashcode) \
 	((hashcode) % NUM_BUFFER_PARTITIONS)
 #define BufMappingPartitionLock(hashcode) \
-	(&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + \
-		BufTableHashPartition(hashcode)].lock)
+	(&BufferMappingLWLockArray[BufTableHashPartition(hashcode)].lock)
 #define BufMappingPartitionLockByIndex(i) \
-	(&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + (i)].lock)
+	(&BufferMappingLWLockArray[i].lock)
 
 /*
  *	BufferDesc -- shared descriptor/state data for a single shared buffer.
@@ -192,6 +191,7 @@ typedef union BufferDescPadded
 	((LWLock*) (&(bdesc)->content_lock))
 
 extern PGDLLIMPORT LWLockMinimallyPadded *BufferIOLWLockArray;
+extern PGDLLIMPORT LWLockPadded *BufferMappingLWLockArray;
 
 /*
  * The freeNext field is either the index of the next freelist entry,
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index 6b4e365..97c04b8 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -458,6 +458,8 @@ typedef enum
 								 * worker */
 } DeadLockState;
 
+extern PGDLLIMPORT LWLockPadded *LockHashLWLockArray;
+
 /*
  * The lockmgr's shared hash tables are partitioned to reduce contention.
  * To determine which partition a given locktag belongs to, compute the tag's
@@ -467,10 +469,9 @@ typedef enum
 #define LockHashPartition(hashcode) \
 	((hashcode) % NUM_LOCK_PARTITIONS)
 #define LockHashPartitionLock(hashcode) \
-	(&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + \
-		LockHashPartition(hashcode)].lock)
+	(&LockHashLWLockArray[LockHashPartition(hashcode)].lock)
 #define LockHashPartitionLockByIndex(i) \
-	(&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
+	(&LockHashLWLockArray[i].lock)
 
 /*
  * The deadlock detector needs to be able to access lockGroupLeader and
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 2bbe1b6..2b3ca71 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -149,14 +149,6 @@ extern PGDLLIMPORT int NamedLWLockTrancheRequests;
 #define LOG2_NUM_PREDICATELOCK_PARTITIONS  4
 #define NUM_PREDICATELOCK_PARTITIONS  (1 << LOG2_NUM_PREDICATELOCK_PARTITIONS)
 
-/* Offsets for various chunks of preallocated lwlocks. */
-#define BUFFER_MAPPING_LWLOCK_OFFSET	NUM_INDIVIDUAL_LWLOCKS
-#define LOCK_MANAGER_LWLOCK_OFFSET		\
-	(BUFFER_MAPPING_LWLOCK_OFFSET + NUM_BUFFER_PARTITIONS)
-#define PREDICATELOCK_MANAGER_LWLOCK_OFFSET \
-	(LOCK_MANAGER_LWLOCK_OFFSET + NUM_LOCK_PARTITIONS)
-#define NUM_FIXED_LWLOCKS \
-	(PREDICATELOCK_MANAGER_LWLOCK_OFFSET + NUM_PREDICATELOCK_PARTITIONS)
 
 typedef enum LWLockMode
 {
@@ -196,8 +188,6 @@ extern void InitLWLockAccess(void);
 extern void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks);
 extern LWLockPadded *GetNamedLWLockTranche(const char *tranche_name);
 
-extern LWLock *LWLockAssign(void);
-
 /*
  * There is another, more flexible method of obtaining lwlocks. First, call
  * LWLockNewTrancheId just once to obtain a tranche ID; this allocates from
diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h
index a66b5b7..a76d7de 100644
--- a/src/include/storage/predicate.h
+++ b/src/include/storage/predicate.h
@@ -14,6 +14,7 @@
 #ifndef PREDICATE_H
 #define PREDICATE_H
 
+#include "storage/lwlock.h"
 #include "utils/relcache.h"
 #include "utils/snapshot.h"
 
@@ -27,6 +28,7 @@ extern int	max_predicate_locks_per_xact;
 /* Number of SLRU buffers to use for predicate locking */
 #define NUM_OLDSERXID_BUFFERS	16
 
+extern PGDLLIMPORT LWLockPadded *PredicateLockHashLWLockArray;
 
 /*
  * function prototypes
