From 7aa815a7aadd0dcc0515dfc3a88677deb0ca11ff Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Fri, 6 Sep 2019 14:27:25 +0900
Subject: [PATCH] Make pg_promote() detect postmaster death while waiting for
 promotion to end.

Previously even if postmaster died and WaitLatch() woke up with that event
while pg_promote() was waiting for the standby promotion to finish,
pg_promote() did nothing special and kept waiting until timeout occurred.
This could cause a busy loop.

This patch make pg_promote() return false immediately when postmaster
dies, to avoid such a busy loop.

Back-patch to v12 where pg_promote() was added.

Author: Fujii Masao
Reviewed-by: Michael Paquier
Discussion: https://postgr.es/m/CAHGQGwEs9ROgSp+QF+YdDU+xP8W=CY1k-_Ov-d_Z3JY+to3eXA@mail.gmail.com
---
 src/backend/access/transam/xlogfuncs.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index b35043bf718..05704d33780 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -759,6 +759,8 @@ pg_promote(PG_FUNCTION_ARGS)
 #define WAITS_PER_SECOND 10
 	for (i = 0; i < WAITS_PER_SECOND * wait_seconds; i++)
 	{
+		int			rc;
+
 		ResetLatch(MyLatch);
 
 		if (!RecoveryInProgress())
@@ -766,10 +768,17 @@ pg_promote(PG_FUNCTION_ARGS)
 
 		CHECK_FOR_INTERRUPTS();
 
-		(void) WaitLatch(MyLatch,
-						 WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-						 1000L / WAITS_PER_SECOND,
-						 WAIT_EVENT_PROMOTE);
+		rc = WaitLatch(MyLatch,
+					   WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+					   1000L / WAITS_PER_SECOND,
+					   WAIT_EVENT_PROMOTE);
+
+		/*
+		 * Emergency bailout if postmaster has died.  This is to avoid the
+		 * necessity for manual cleanup of all postmaster children.
+		 */
+		if (rc & WL_POSTMASTER_DEATH)
+			PG_RETURN_BOOL(false);
 	}
 
 	ereport(WARNING,
-- 
GitLab