diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 477982d..a555c91 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -319,7 +319,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
 	gxact->proc.inCommit = false;
 	gxact->proc.vacuumFlags = 0;
 	gxact->proc.lwWaiting = false;
-	gxact->proc.lwExclusive = false;
+	gxact->proc.lwMode = LW_SHARED;
 	gxact->proc.lwWaitLink = NULL;
 	gxact->proc.waitLock = NULL;
 	gxact->proc.waitProcLock = NULL;
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 1a48485..5b60029 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -359,7 +359,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
 		 */
 		Assert(TransactionIdIsValid(proc->xid));
 
-		LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+		LWLockAcquire(ProcArrayLock, LW_SHARED2);
 
 		proc->xid = InvalidTransactionId;
 		proc->lxid = InvalidLocalTransactionId;
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 079eb29..8658c83 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -32,6 +32,7 @@
 #include "storage/proc.h"
 #include "storage/spin.h"
 
+#define LWLOCK_STATS 1
 
 /* We use the ShmemLock spinlock to protect LWLockAssign */
 extern slock_t *ShmemLock;
@@ -42,7 +43,8 @@ typedef struct LWLock
 	slock_t		mutex;			/* Protects LWLock and queue of PGPROCs */
 	bool		releaseOK;		/* T if ok to release waiters */
 	char		exclusive;		/* # of exclusive holders (0 or 1) */
-	int			shared;			/* # of shared holders (0..MaxBackends) */
+	int			shared1;		/* # of shared1 holders (0..MaxBackends) */
+	int			shared2;		/* # of shared2 holders (0..MaxBackends) */
 	PGPROC	   *head;			/* head of list of waiting PGPROCs */
 	PGPROC	   *tail;			/* tail of list of waiting PGPROCs */
 	/* tail is undefined when head is NULL */
@@ -92,7 +94,8 @@ static bool lock_addin_request_allowed = true;
 
 #ifdef LWLOCK_STATS
 static int	counts_for_pid = 0;
-static int *sh_acquire_counts;
+static int *sh1_acquire_counts;
+static int *sh2_acquire_counts;
 static int *ex_acquire_counts;
 static int *block_counts;
 #endif
@@ -104,9 +107,9 @@ inline static void
 PRINT_LWDEBUG(const char *where, LWLockId lockid, const volatile LWLock *lock)
 {
 	if (Trace_lwlocks)
-		elog(LOG, "%s(%d): excl %d shared %d head %p rOK %d",
+		elog(LOG, "%s(%d): excl %d shared1 %d shared2 %d head %p rOK %d",
 			 where, (int) lockid,
-			 (int) lock->exclusive, lock->shared, lock->head,
+			 (int) lock->exclusive, lock->shared1, lock->shared2, lock->head,
 			 (int) lock->releaseOK);
 }
 
@@ -135,9 +138,9 @@ print_lwlock_stats(int code, Datum arg)
 
 	for (i = 0; i < numLocks; i++)
 	{
-		if (sh_acquire_counts[i] || ex_acquire_counts[i] || block_counts[i])
-			fprintf(stderr, "PID %d lwlock %d: shacq %u exacq %u blk %u\n",
-					MyProcPid, i, sh_acquire_counts[i], ex_acquire_counts[i],
+		if (sh1_acquire_counts[i] || sh2_acquire_counts[i] || ex_acquire_counts[i] || block_counts[i])
+			fprintf(stderr, "PID %d lwlock %d: shacq1 %u shacq2 %u exacq %u blk %u\n",
+					MyProcPid, i, sh1_acquire_counts[i], sh2_acquire_counts[i], ex_acquire_counts[i],
 					block_counts[i]);
 	}
 
@@ -268,7 +271,8 @@ CreateLWLocks(void)
 		SpinLockInit(&lock->lock.mutex);
 		lock->lock.releaseOK = true;
 		lock->lock.exclusive = 0;
-		lock->lock.shared = 0;
+		lock->lock.shared1 = 0;
+		lock->lock.shared2 = 0;
 		lock->lock.head = NULL;
 		lock->lock.tail = NULL;
 	}
@@ -336,7 +340,8 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
 		int		   *LWLockCounter = (int *) ((char *) LWLockArray - 2 * sizeof(int));
 		int			numLocks = LWLockCounter[1];
 
-		sh_acquire_counts = calloc(numLocks, sizeof(int));
+		sh1_acquire_counts = calloc(numLocks, sizeof(int));
+		sh2_acquire_counts = calloc(numLocks, sizeof(int));
 		ex_acquire_counts = calloc(numLocks, sizeof(int));
 		block_counts = calloc(numLocks, sizeof(int));
 		counts_for_pid = MyProcPid;
@@ -345,8 +350,10 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
 	/* Count lock acquisition attempts */
 	if (mode == LW_EXCLUSIVE)
 		ex_acquire_counts[lockid]++;
+	else if (mode == LW_SHARED)
+		sh1_acquire_counts[lockid]++;
 	else
-		sh_acquire_counts[lockid]++;
+		sh2_acquire_counts[lockid]++;
 #endif   /* LWLOCK_STATS */
 
 	/*
@@ -397,7 +404,7 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
 		/* If I can get the lock, do so quickly. */
 		if (mode == LW_EXCLUSIVE)
 		{
-			if (lock->exclusive == 0 && lock->shared == 0)
+			if (lock->exclusive == 0 && lock->shared1 == 0 && lock->shared2 == 0)
 			{
 				lock->exclusive++;
 				mustwait = false;
@@ -405,11 +412,21 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
 			else
 				mustwait = true;
 		}
+		else if (mode == LW_SHARED)
+		{
+			if (lock->exclusive == 0 && lock->shared2 == 0)
+			{
+				lock->shared1++;
+				mustwait = false;
+			}
+			else
+				mustwait = true;
+		}
 		else
 		{
-			if (lock->exclusive == 0)
+			if (lock->exclusive == 0 && lock->shared1 == 0)
 			{
-				lock->shared++;
+				lock->shared2++;
 				mustwait = false;
 			}
 			else
@@ -430,7 +447,7 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
 			elog(PANIC, "cannot wait without a PGPROC structure");
 
 		proc->lwWaiting = true;
-		proc->lwExclusive = (mode == LW_EXCLUSIVE);
+		proc->lwMode = mode;
 		proc->lwWaitLink = NULL;
 		if (lock->head == NULL)
 			lock->head = proc;
@@ -525,7 +542,7 @@ LWLockConditionalAcquire(LWLockId lockid, LWLockMode mode)
 	/* If I can get the lock, do so quickly. */
 	if (mode == LW_EXCLUSIVE)
 	{
-		if (lock->exclusive == 0 && lock->shared == 0)
+		if (lock->exclusive == 0 && lock->shared1 == 0 && lock->shared2 == 0)
 		{
 			lock->exclusive++;
 			mustwait = false;
@@ -533,11 +550,21 @@ LWLockConditionalAcquire(LWLockId lockid, LWLockMode mode)
 		else
 			mustwait = true;
 	}
+	else if (mode == LW_SHARED)
+	{
+		if (lock->exclusive == 0 && lock->shared2 == 0)
+		{
+			lock->shared1++;
+			mustwait = false;
+		}
+		else
+			mustwait = true;
+	}
 	else
 	{
-		if (lock->exclusive == 0)
+		if (lock->exclusive == 0 && lock->shared1 == 0)
 		{
-			lock->shared++;
+			lock->shared2++;
 			mustwait = false;
 		}
 		else
@@ -598,10 +625,12 @@ LWLockRelease(LWLockId lockid)
 	/* Release my hold on lock */
 	if (lock->exclusive > 0)
 		lock->exclusive--;
+	else if (lock->shared1 > 0)
+		lock->shared1--;
 	else
 	{
-		Assert(lock->shared > 0);
-		lock->shared--;
+		Assert(lock->shared2 > 0);
+		lock->shared2--;
 	}
 
 	/*
@@ -613,7 +642,8 @@ LWLockRelease(LWLockId lockid)
 	head = lock->head;
 	if (head != NULL)
 	{
-		if (lock->exclusive == 0 && lock->shared == 0 && lock->releaseOK)
+		if (lock->exclusive == 0 && lock->shared1 == 0 && lock->shared2 == 0
+			&& lock->releaseOK)
 		{
 			/*
 			 * Remove the to-be-awakened PGPROCs from the queue.  If the front
@@ -621,10 +651,12 @@ LWLockRelease(LWLockId lockid)
 			 * as many waiters as want shared access.
 			 */
 			proc = head;
-			if (!proc->lwExclusive)
+			if (proc->lwMode != LW_EXCLUSIVE)
 			{
+				LWLockMode		wake_mode = proc->lwMode;
+
 				while (proc->lwWaitLink != NULL &&
-					   !proc->lwWaitLink->lwExclusive)
+					   proc->lwWaitLink->lwMode == wake_mode)
 					proc = proc->lwWaitLink;
 			}
 			/* proc is now the last PGPROC to be released */
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index eda3a98..be48a47 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -326,7 +326,7 @@ InitProcess(void)
 	if (IsAutoVacuumWorkerProcess())
 		MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM;
 	MyProc->lwWaiting = false;
-	MyProc->lwExclusive = false;
+	MyProc->lwMode = LW_SHARED;
 	MyProc->lwWaitLink = NULL;
 	MyProc->waitLock = NULL;
 	MyProc->waitProcLock = NULL;
@@ -480,7 +480,7 @@ InitAuxiliaryProcess(void)
 	MyProc->inCommit = false;
 	MyProc->vacuumFlags = 0;
 	MyProc->lwWaiting = false;
-	MyProc->lwExclusive = false;
+	MyProc->lwMode = LW_SHARED;
 	MyProc->lwWaitLink = NULL;
 	MyProc->waitLock = NULL;
 	MyProc->waitProcLock = NULL;
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 438a48d..3b1c1c0 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -94,7 +94,8 @@ typedef enum LWLockId
 typedef enum LWLockMode
 {
 	LW_EXCLUSIVE,
-	LW_SHARED
+	LW_SHARED,
+	LW_SHARED2
 } LWLockMode;
 
 
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 6e798b1..d4220a7 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -116,7 +116,7 @@ struct PGPROC
 
 	/* Info about LWLock the process is currently waiting for, if any. */
 	bool		lwWaiting;		/* true if waiting for an LW lock */
-	bool		lwExclusive;	/* true if waiting for exclusive access */
+	LWLockMode	lwMode;			/* mode we're waiting for */
 	struct PGPROC *lwWaitLink;	/* next waiter for same LW lock */
 
 	/* Info about lock the process is currently waiting for, if any. */