diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index e4645a3..c2ec9d3 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -635,6 +635,15 @@ typedef struct XLogCtlData
 	TimeLineID	RecoveryTargetTLI;
 
 	/*
+	 * Set of fields indicating the position to return to callers of
+	 * do_pg_stop_backup. This field gets updated when the minimum
+	 * recovery point is refreshed and when a new restart point is
+	 * created even if the minimum recovery point is not.
+	 */
+	XLogRecPtr	stopBackupLSN;
+	TimeLineID	stopBackupTLI;
+
+	/*
 	 * timestamp of when we started replaying the current chunk of WAL data,
 	 * only relevant for replication or archive recovery
 	 */
@@ -2529,10 +2538,19 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force)
 		 * value as the min recovery point would prevent us from coming up at
 		 * all.  Instead, we just log a warning and continue with recovery.
 		 * (See also the comments about corrupt LSNs in XLogFlush.)
+		 *
+		 * Refresh at the same time the LSN and timeline positions for the
+		 * stop positions of backups.  This is done here to not have to take
+		 * info_lck more than necessary, and those values are related to
+		 * the minimum recovery point, except that they get updated even
+		 * if minRecoveryPoint is not refreshed when creating a restart
+		 * point, but those are.
 		 */
 		SpinLockAcquire(&XLogCtl->info_lck);
 		newMinRecoveryPoint = XLogCtl->replayEndRecPtr;
 		newMinRecoveryPointTLI = XLogCtl->replayEndTLI;
+		XLogCtl->stopBackupLSN = XLogCtl->replayEndRecPtr;
+		XLogCtl->stopBackupTLI = XLogCtl->replayEndTLI;
 		SpinLockRelease(&XLogCtl->info_lck);
 
 		if (!force && newMinRecoveryPoint < lsn)
@@ -6657,6 +6675,8 @@ StartupXLOG(void)
 		XLogCtl->recoveryLastXTime = 0;
 		XLogCtl->currentChunkStartTime = 0;
 		XLogCtl->recoveryPause = false;
+		XLogCtl->stopBackupLSN = XLogCtl->replayEndRecPtr;
+		XLogCtl->stopBackupTLI = XLogCtl->replayEndTLI;
 		SpinLockRelease(&XLogCtl->info_lck);
 
 		/* Also ensure XLogReceiptTime has a sane value */
@@ -8779,6 +8799,8 @@ CreateRestartPoint(int flags)
 	/* Also update the info_lck-protected copy */
 	SpinLockAcquire(&XLogCtl->info_lck);
 	XLogCtl->RedoRecPtr = lastCheckPoint.redo;
+	XLogCtl->stopBackupLSN = XLogCtl->replayEndRecPtr;
+	XLogCtl->stopBackupTLI = XLogCtl->replayEndTLI;;
 	SpinLockRelease(&XLogCtl->info_lck);
 
 	/*
@@ -10397,11 +10419,15 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 	/*
 	 * During recovery, we don't write an end-of-backup record. We assume that
 	 * pg_control was backed up last and its minimum recovery point can be
-	 * available as the backup end location. Since we don't have an
-	 * end-of-backup record, we use the pg_control value to check whether
-	 * we've reached the end of backup when starting recovery from this
-	 * backup. We have no way of checking if pg_control wasn't backed up last
-	 * however.
+	 * available as the backup end location.  Since we don't have an
+	 * end-of-backup record, we use the in-memory state of XLOG to decide
+	 * what are the end location using stopBackupLSN and stopBackupTLI
+	 * which are set when the minimum recovery LSN is bumped or when a
+	 * restart point is created the minimum recovery LSN was not updated
+	 * because no data has been flushed when replaying records. This
+	 * prevents cases where the start location of a backup is newer than
+	 * its end location because the minimum recovery point may not be
+	 * updated.
 	 *
 	 * 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
@@ -10409,10 +10435,9 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 	 * required files are available, a user should wait for them to be
 	 * archived, or include them into the backup.
 	 *
-	 * We return the current minimum recovery point as the backup end
-	 * location. Note that it can be greater than the exact backup end
-	 * location if the minimum recovery point is updated after the backup of
-	 * pg_control. This is harmless for current uses.
+	 * Note that the backup end location can be greater than the exact backup
+	 * end location if the minimum recovery point is updated after the backup
+	 * of 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,
@@ -10430,6 +10455,8 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 		 */
 		SpinLockAcquire(&XLogCtl->info_lck);
 		recptr = XLogCtl->lastFpwDisableRecPtr;
+		stoppoint = XLogCtl->stopBackupLSN;
+		stoptli = XLogCtl->stopBackupTLI;
 		SpinLockRelease(&XLogCtl->info_lck);
 
 		if (startpoint <= recptr)
@@ -10442,12 +10469,6 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 				 "Enable full_page_writes and run CHECKPOINT on the master, "
 					 "and then try an online backup again.")));
 
-
-		LWLockAcquire(ControlFileLock, LW_SHARED);
-		stoppoint = ControlFile->minRecoveryPoint;
-		stoptli = ControlFile->minRecoveryPointTLI;
-		LWLockRelease(ControlFileLock);
-
 		if (stoptli_p)
 			*stoptli_p = stoptli;
 		return stoppoint;
diff --git a/src/test/recovery/t/001_stream_rep.pl b/src/test/recovery/t/001_stream_rep.pl
index 7b42f21..cee4768 100644
--- a/src/test/recovery/t/001_stream_rep.pl
+++ b/src/test/recovery/t/001_stream_rep.pl
@@ -24,6 +24,11 @@ $node_standby_1->start;
 # pg_basebackup works on a standby).
 $node_standby_1->backup($backup_name);
 
+# Take a second backup of the standby while the master is offline.
+$node_master->stop;
+$node_standby_1->backup('my_backup_2');
+$node_master->start;
+
 # Create second standby node linking to standby 1
 my $node_standby_2 = get_new_node('standby_2');
 $node_standby_2->init_from_backup($node_standby_1, $backup_name,
