diff --git a/doc/src/sgml/recovery-config.sgml b/doc/src/sgml/recovery-config.sgml
index 0f1ff34..a145a3f 100644
--- a/doc/src/sgml/recovery-config.sgml
+++ b/doc/src/sgml/recovery-config.sgml
@@ -289,12 +289,39 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
       </term>
       <listitem>
        <para>
-        Specifies whether recovery should pause when the recovery target
-        is reached. The default is true.
-        This is intended to allow queries to be executed against the
-        database to check if this recovery target is the most desirable
-        point for recovery. The paused state can be resumed by using
-        <function>pg_xlog_replay_resume()</> (See
+        Alias for action_at_recovery_target, <literal>true</> is same as
+        action_at_recovery_target = <literal>pause</> and <literal>false</>
+        is same as action_at_recovery_target = <literal>promote</>.
+       </para>
+       <para>
+        This setting has no effect if <xref linkend="guc-hot-standby"> is not
+        enabled, or if no recovery target is set.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     </variablelist>
+
+     <varlistentry id="action-at-recovery-target"
+                   xreflabel="action_at_recovery_target">
+      <term><varname>action_at_recovery_target</varname> (<type>enum</type>)
+      <indexterm>
+        <primary><varname>action_at_recovery_target</> recovery parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Specifies what action the server should take once the recovery target is
+        reached. The default is <literal>pause</>, which means recovery will
+        be paused. <literal>promote</> means recovery process will finish and
+        the server will start to accept connections.
+        Finally <literal>shutdown</> will stop the server after reaching the
+        recovery target.
+       </para>
+        The intended use of <literal>pause</> setting is to allow queries to be
+        executed against the database to check if this recovery target is the
+        most desirable point for recovery. The paused state can be resumed by
+        using <function>pg_xlog_replay_resume()</> (See
         <xref linkend="functions-recovery-control-table">), which then
         causes recovery to end. If this recovery target is not the
         desired stopping point, then shutdown the server, change the
@@ -302,8 +329,23 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
         continue recovery.
        </para>
        <para>
-        This setting has no effect if <xref linkend="guc-hot-standby"> is not
-        enabled, or if no recovery target is set.
+        The <literal>shutdown</> setting is useful to have instance ready at
+        exact replay point desired.
+        The instance will still be able to replay more WAL records (and in fact
+        will have to replay WAL records since last checkpoint next time it is
+        started).
+       </para>
+       <para>
+        Note that because <filename>recovery.conf</> will not be renamed when
+        <varname>action_at_recovery_target</> is set to <literal>shutdown</>,
+        any subsequent start will end with immediate shutdown unless the
+        configuration is changed or the <filename>recovery.conf</> is removed
+        manually.
+       </para>
+       <para>
+        This setting has no effect if no recovery target is set.
+        If <xref linkend="guc-hot-standby"> is not enabled, a setting of
+        <literal>pause</> will act the same as <literal>shutdown</>.
        </para>
       </listitem>
      </varlistentry>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 6053127..29b7fc5 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -228,7 +228,7 @@ static char *recoveryEndCommand = NULL;
 static char *archiveCleanupCommand = NULL;
 static RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET;
 static bool recoveryTargetInclusive = true;
-static bool recoveryPauseAtTarget = true;
+static RecoveryTargetAction actionAtRecoveryTarget = RECOVERY_TARGET_ACTION_PAUSE;
 static TransactionId recoveryTargetXid;
 static TimestampTz recoveryTargetTime;
 static char *recoveryTargetName;
@@ -4643,6 +4643,9 @@ readRecoveryCommandFile(void)
 	ConfigVariable *item,
 			   *head = NULL,
 			   *tail = NULL;
+	bool		recoveryPauseAtTargetSet = false;
+	bool		actionAtRecoveryTargetSet = false;
+
 
 	fd = AllocateFile(RECOVERY_COMMAND_FILE, "r");
 	if (fd == NULL)
@@ -4688,13 +4691,43 @@ readRecoveryCommandFile(void)
 		}
 		else if (strcmp(item->name, "pause_at_recovery_target") == 0)
 		{
+			bool recoveryPauseAtTarget;
+
 			if (!parse_bool(item->value, &recoveryPauseAtTarget))
 				ereport(ERROR,
 						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 						 errmsg("parameter \"%s\" requires a Boolean value", "pause_at_recovery_target")));
+
 			ereport(DEBUG2,
 					(errmsg_internal("pause_at_recovery_target = '%s'",
 									 item->value)));
+
+			actionAtRecoveryTarget = recoveryPauseAtTarget ?
+									 RECOVERY_TARGET_ACTION_PAUSE :
+									 RECOVERY_TARGET_ACTION_PROMOTE;
+
+			recoveryPauseAtTargetSet = true;
+		}
+		else if (strcmp(item->name, "action_at_recovery_target") == 0)
+		{
+			if (strcmp(item->value, "pause") == 0)
+				actionAtRecoveryTarget = RECOVERY_TARGET_ACTION_PAUSE;
+			else if (strcmp(item->value, "promote") == 0)
+				actionAtRecoveryTarget = RECOVERY_TARGET_ACTION_PROMOTE;
+			else if (strcmp(item->value, "shutdown") == 0)
+				actionAtRecoveryTarget = RECOVERY_TARGET_ACTION_SHUTDOWN;
+			else
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+						 errmsg("invalid value for recovery parameter \"%s\"",
+								"action_at_recovery_target"),
+						 errhint("The allowed values are \"pause\", \"promote\" and \"shutdown\".")));
+
+			ereport(DEBUG2,
+					(errmsg_internal("action_at_recovery_target = '%s'",
+									 item->value)));
+
+			actionAtRecoveryTargetSet = true;
 		}
 		else if (strcmp(item->name, "recovery_target_timeline") == 0)
 		{
@@ -4859,6 +4892,25 @@ readRecoveryCommandFile(void)
 							RECOVERY_COMMAND_FILE)));
 	}
 
+	/*
+	 * Check for mutually exclusive parameters
+	 */
+	if (recoveryPauseAtTargetSet && actionAtRecoveryTargetSet)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("cannot set both \"%s\" and \"%s\" recovery parameters",
+						"pause_at_recovery_target",
+						"action_at_recovery_target"),
+				 errhint("The \"pause_at_recovery_target\" is deprecated.")));
+
+
+	/*
+	 * Override any inconsistent requests
+	 */
+	if (actionAtRecoveryTarget == RECOVERY_TARGET_ACTION_PAUSE &&
+		standbyState == STANDBY_DISABLED)
+		actionAtRecoveryTarget = RECOVERY_TARGET_ACTION_SHUTDOWN;
+
 	/* Enable fetching from archive recovery area */
 	ArchiveRecoveryRequested = true;
 
@@ -6408,10 +6460,41 @@ StartupXLOG(void)
 			 * end of main redo apply loop
 			 */
 
-			if (recoveryPauseAtTarget && reachedStopPoint)
+			if (reachedStopPoint)
 			{
-				SetRecoveryPause(true);
-				recoveryPausesHere();
+				if (!reachedConsistency)
+					ereport(FATAL,
+						(errmsg("requested recovery stop point is before consistent recovery point")));
+
+				/*
+				 * This is the last point where we can restart recovery with a
+				 * new recovery target, if we shutdown and begin again. After
+				 * this, Resource Managers may choose to do permanent corrective
+				 * actions at end of recovery.
+				 */
+				switch (actionAtRecoveryTarget)
+				{
+					case RECOVERY_TARGET_ACTION_SHUTDOWN:
+							ereport(LOG, (errmsg("shutting down at recovery target")));
+							/*
+							 * Tell postmaster to shutdown, which then calls us
+							 * back to exit cleanly.
+							 */
+							if (kill(PostmasterPid, SIGINT))
+								ereport(FATAL,
+										(errmsg("failed to send signal to postmaster: %m")));
+
+							/* drop into pause while waiting for clean shutdown */
+
+					case RECOVERY_TARGET_ACTION_PAUSE:
+							SetRecoveryPause(true);
+							recoveryPausesHere();
+
+							/* drop into promote */
+
+					case RECOVERY_TARGET_ACTION_PROMOTE:
+							break;
+				}
 			}
 
 			/* Allow resource managers to do any required cleanup. */
@@ -6429,6 +6512,7 @@ StartupXLOG(void)
 				ereport(LOG,
 					 (errmsg("last completed transaction was at log time %s",
 							 timestamptz_to_str(xtime))));
+
 			InRedo = false;
 		}
 		else
@@ -6489,13 +6573,6 @@ StartupXLOG(void)
 		(EndOfLog < minRecoveryPoint ||
 		 !XLogRecPtrIsInvalid(ControlFile->backupStartPoint)))
 	{
-		if (reachedStopPoint)
-		{
-			/* stopped because of stop request */
-			ereport(FATAL,
-					(errmsg("requested recovery stop point is before consistent recovery point")));
-		}
-
 		/*
 		 * Ran off end of WAL before reaching end-of-backup WAL record, or
 		 * minRecoveryPoint. That's usually a bad sign, indicating that you
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 19b2ef8..04866e6 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -204,6 +204,16 @@ typedef struct xl_end_of_recovery
 } xl_end_of_recovery;
 
 /*
+ * Recovery target action.
+ */
+typedef enum
+{
+	RECOVERY_TARGET_ACTION_PAUSE,
+	RECOVERY_TARGET_ACTION_PROMOTE,
+	RECOVERY_TARGET_ACTION_SHUTDOWN,
+} RecoveryTargetAction;
+
+/*
  * Method table for resource managers.
  *
  * This struct must be kept in sync with the PG_RMGR definition in
