diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml
index 7820de9..6bebf3d 100644
--- a/doc/src/sgml/backup.sgml
+++ b/doc/src/sgml/backup.sgml
@@ -1012,10 +1012,12 @@ SELECT pg_start_backup('label', true);
 <programlisting>
 SELECT pg_stop_backup();
 </programlisting>
-     This terminates the backup mode and performs an automatic switch to
-     the next WAL segment.  The reason for the switch is to arrange for
-     the last WAL segment file written during the backup interval to be
-     ready to archive.
+     When called on a master it terminates the backup mode and performs
+     an automatic switch to the next WAL segment. The reason for the switch
+     is to arrange for the last WAL segment written during the backup
+     interval to be ready to archive. When called on a standby the WAL
+     segment switch must be performed manually on the primary if it does
+     not happen due to normal write activity.
     </para>
    </listitem>
    <listitem>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 3631922..899e52e 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -18597,7 +18597,17 @@ postgres=# select pg_start_backup('label_goes_here');
     WAL to be archived.  This behavior is only useful for backup
     software which independently monitors WAL archiving. Otherwise, WAL
     required to make the backup consistent might be missing and make the backup
-    useless.
+    useless. If the second parameter <parameter>wait_for_archive</> is true and
+    the backup is taken on a standby, <function>pg_stop_backup</> waits for WAL
+    to be archived when <varname>archive_mode</> = <literal>always</>.  Enforcing
+    manually a WAL segment switch to happen with for example
+    <function>pg_switch_wal</> may be necessary if the primary has low activity
+    to allow the backup to complete. Using <varname>statement_timeout</> to
+    limit the amount of time to wait or switching <parameter>wait_for_archive</>
+    to <literal>false</> will control the wait time, though all the WAL segments
+    necessary to recover into a consistent state from the backup taken may not be
+    archived at the time <function>pg_stop_backup</> returns its status to the
+    caller.
    </para>
 
    <para>
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 3654543..7b4769e 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -10363,10 +10363,9 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p,
 
 				/*
 				 * During recovery, since we don't use the end-of-backup WAL
-				 * record and don't write the backup history file, the
-				 * starting WAL location doesn't need to be unique. This means
-				 * that two base backups started at the same time might use
-				 * the same checkpoint as starting locations.
+				 * record, the starting WAL location doesn't need to be unique.
+				 * This means that two base backups started at the same time
+				 * might use the same checkpoint as starting locations.
 				 */
 				gotUniqueStartpoint = true;
 			}
@@ -10881,10 +10880,10 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 	 * however.
 	 *
 	 * We don't force a switch to new WAL file and wait for all the required
-	 * files to be archived. This is okay if we use the backup to start the
-	 * standby. But, if it's for an archive recovery, to ensure all the
-	 * required files are available, a user should wait for them to be
-	 * archived, or include them into the backup.
+	 * files to be archived if waitforarchive is false. This is okay if we use
+	 * the backup to start the standby. But, if it's for an archive recovery,
+	 * to ensure all the required files are available, a user should set
+	 * waitforarchive true and wait for them to be archived.
 	 *
 	 * We return the current minimum recovery point as the backup end
 	 * location. Note that it can be greater than the exact backup end
@@ -10892,10 +10891,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 	 * pg_control. This is harmless for current uses.
 	 *
 	 * XXX currently a backup history file is for informational and debug
-	 * purposes only. It's not essential for an online backup. Furthermore,
-	 * even if it's created, it will not be archived during recovery because
-	 * an archiver is not invoked. So it doesn't seem worthwhile to write a
-	 * backup history file during recovery.
+	 * purposes only. It's not essential for an online backup.
 	 */
 	if (backup_started_in_recovery)
 	{
@@ -10924,28 +10920,26 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 		stoppoint = ControlFile->minRecoveryPoint;
 		stoptli = ControlFile->minRecoveryPointTLI;
 		LWLockRelease(ControlFileLock);
-
-		if (stoptli_p)
-			*stoptli_p = stoptli;
-		return stoppoint;
 	}
+	else
+	{
+		/*
+		 * Write the backup-end xlog record
+		 */
+		XLogBeginInsert();
+		XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
+		stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
+		stoptli = ThisTimeLineID;
 
-	/*
-	 * Write the backup-end xlog record
-	 */
-	XLogBeginInsert();
-	XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
-	stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
-	stoptli = ThisTimeLineID;
-
-	/*
-	 * Force a switch to a new xlog segment file, so that the backup is valid
-	 * as soon as archiver moves out the current segment file.
-	 */
-	RequestXLogSwitch(false);
+		/*
+		 * Force a switch to a new xlog segment file, so that the backup is valid
+		 * as soon as archiver moves out the current segment file.
+		 */
+		RequestXLogSwitch(false);
+	}
 
 	XLByteToPrevSeg(stoppoint, _logSegNo);
-	XLogFileName(stopxlogfilename, ThisTimeLineID, _logSegNo);
+	XLogFileName(stopxlogfilename, stoptli, _logSegNo);
 
 	/* Use the log timezone here, not the session timezone */
 	stamp_time = (pg_time_t) time(NULL);
@@ -10957,7 +10951,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 	 * Write the backup history file
 	 */
 	XLByteToSeg(startpoint, _logSegNo);
-	BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logSegNo,
+	BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
 						  (uint32) (startpoint % XLogSegSize));
 	fp = AllocateFile(histfilepath, "w");
 	if (!fp)
@@ -11005,13 +10999,16 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 	 * or you can set statement_timeout.  Also, some notices are issued to
 	 * clue in anyone who might be doing this interactively.
 	 */
-	if (waitforarchive && XLogArchivingActive())
+
+	if (waitforarchive &&
+		((!backup_started_in_recovery && XLogArchivingActive()) ||
+		 (backup_started_in_recovery && XLogArchivingAlways())))
 	{
 		XLByteToPrevSeg(stoppoint, _logSegNo);
-		XLogFileName(lastxlogfilename, ThisTimeLineID, _logSegNo);
+		XLogFileName(lastxlogfilename, stoptli, _logSegNo);
 
 		XLByteToSeg(startpoint, _logSegNo);
-		BackupHistoryFileName(histfilename, ThisTimeLineID, _logSegNo,
+		BackupHistoryFileName(histfilename, stoptli, _logSegNo,
 							  (uint32) (startpoint % XLogSegSize));
 
 		seconds_before_warning = 60;
@@ -11034,12 +11031,13 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 			if (++waits >= seconds_before_warning)
 			{
 				seconds_before_warning *= 2;	/* This wraps in >10 years... */
-				ereport(WARNING,
-						(errmsg("pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)",
-								waits),
-						 errhint("Check that your archive_command is executing properly.  "
-								 "pg_stop_backup can be canceled safely, "
-								 "but the database backup will not be usable without all the WAL segments.")));
+					ereport(WARNING,
+							(errmsg("pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)",
+									waits),
+							 errhint("Either archive_command is failing or not enough WAL has been "
+									 "generated to require a segment switch. Run pg_switch_wal() to "
+									 "request a WAL switch and monitor your logs to check that your "
+									 "archive_command is executing properly.")));
 			}
 		}
 
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index f9b49ba..750bea1 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -294,7 +294,8 @@ pg_switch_wal(PG_FUNCTION_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
 				 errmsg("recovery is in progress"),
-				 errhint("WAL control functions cannot be executed during recovery.")));
+				 errhint("WAL control functions cannot be executed during recovery; "
+						 "they should be executed on the primary instead")));
 
 	switchpoint = RequestXLogSwitch(false);
 
