From b34e788895c33385494674a2a7b8bc93f829b78f Mon Sep 17 00:00:00 2001
From: Kuntal Ghosh <kuntal.ghosh@enterprisedb.com>
Date: Mon, 3 Apr 2017 15:22:33 +0530
Subject: [PATCH] Fix parallel worker counts after a crash

Number of terminated parallel workers should be at least the number
of registered parallel worker. When ForgetBackgroundWorker is called
due to a bgworker crash, we should not increase the terminated parallel
worker count;
---
 src/backend/postmaster/bgworker.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index 10e0f88..9c3aa9a 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -399,7 +399,17 @@ ForgetBackgroundWorker(slist_mutable_iter *cur)
 	Assert(rw->rw_shmem_slot < max_worker_processes);
 	slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
 	if ((rw->rw_worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0)
-		BackgroundWorkerData->parallel_terminate_count++;
+	{
+		/*
+		 * If register count is just initialized, i.e., equals to
+		 * zero, we should not increase the terminate count.
+		 */
+		if (BackgroundWorkerData->parallel_register_count > 0)
+			BackgroundWorkerData->parallel_terminate_count++;
+
+		Assert(BackgroundWorkerData->parallel_register_count >=
+			BackgroundWorkerData->parallel_terminate_count);
+	}
 
 	slot->in_use = false;
 
@@ -931,6 +941,9 @@ RegisterDynamicBackgroundWorker(BackgroundWorker *worker,
 	 * postmaster must not take locks; a memory barrier wouldn't guarantee
 	 * anything useful.
 	 */
+	Assert(BackgroundWorkerData->parallel_register_count >=
+		BackgroundWorkerData->parallel_terminate_count);
+
 	if (parallel && (BackgroundWorkerData->parallel_register_count -
 					 BackgroundWorkerData->parallel_terminate_count) >=
 		max_parallel_workers)
-- 
1.8.3.1

