*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
***************
*** 278,283 **** typedef enum
--- 278,284 ----
  	PM_RECOVERY_CONSISTENT,		/* consistent recovery mode */
  	PM_RUN,						/* normal "database is alive" state */
  	PM_WAIT_BACKUP,				/* waiting for online backup mode to end */
+ 	PM_WAIT_READONLY,			/* waiting for read only backends to exit */
  	PM_WAIT_BACKENDS,			/* waiting for live backends to exit */
  	PM_SHUTDOWN,				/* waiting for bgwriter to do shutdown ckpt */
  	PM_SHUTDOWN_2,				/* waiting for archiver and walsenders to finish */
***************
*** 2165,2171 **** pmdie(SIGNAL_ARGS)
  				/* and the walwriter too */
  				if (WalWriterPID != 0)
  					signal_child(WalWriterPID, SIGTERM);
! 				pmState = PM_WAIT_BACKUP;
  			}
  
  			/*
--- 2166,2173 ----
  				/* and the walwriter too */
  				if (WalWriterPID != 0)
  					signal_child(WalWriterPID, SIGTERM);
! 				/* online backup mode is active only when normal processing */
! 				pmState = (pmState == PM_RUN) ? PM_WAIT_BACKUP : PM_WAIT_READONLY;
  			}
  
  			/*
***************
*** 2840,2845 **** PostmasterStateMachine(void)
--- 2842,2870 ----
  	}
  
  	/*
+ 	 * If we are in a state-machine state that implies waiting for read only
+ 	 * backends to exit, see if they're all gone, and change state if so.
+ 	 */
+ 	if (pmState == PM_WAIT_READONLY)
+ 	{
+ 		/*
+ 		 * PM_WAIT_READONLY state ends when we have no regular backends that
+ 		 * have been started during recovery. Since those backends might be
+ 		 * waiting for the WAL record that conflicts with their queries to be
+ 		 * replayed, recovery and replication need to remain until all read
+ 		 * only backends have been gone away.
+ 		 */
+ 		if (CountChildren(BACKEND_TYPE_NORMAL) == 0)
+ 		{
+ 			if (StartupPID != 0)
+ 				signal_child(StartupPID, SIGTERM);
+ 			if (WalReceiverPID != 0)
+ 				signal_child(WalReceiverPID, SIGTERM);
+ 			pmState = PM_WAIT_BACKENDS;
+ 		}
+ 	}
+ 
+ 	/*
  	 * If we are in a state-machine state that implies waiting for backends to
  	 * exit, see if they're all gone, and change state if so.
  	 */
