From a37a7bfb05d9066676647ade0ecff85ee5cda2c4 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyotaro@lab.ntt.co.jp>
Date: Thu, 9 Jun 2016 14:56:07 +0900
Subject: [PATCH] Make pg_stop_backup on standby give proper end LSN.

pg_basebackup to a replication standby can fail with an error that
says no WAL available. This is caused by that the do_pg_stop_backup
returns the minRecoveryPoint as the backup end point but it is
sometimes too small, that is, going behind backup start point given by
do_pg_start_backup.

We use lastReplayedEndRecPtr instead. It is the last LSN that may be
affect page files on disk, which is suitable for this use.
---
 src/backend/access/transam/xlog.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index b473f19..438b091 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -10409,9 +10409,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
+	 * We return the current last replayed 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
+	 * location if the last replayed 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
@@ -10430,6 +10430,8 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
 		 */
 		SpinLockAcquire(&XLogCtl->info_lck);
 		recptr = XLogCtl->lastFpwDisableRecPtr;
+		stoppoint = XLogCtl->lastReplayedEndRecPtr;
+		stoptli = XLogCtl->lastReplayedTLI;
 		SpinLockRelease(&XLogCtl->info_lck);
 
 		if (startpoint <= recptr)
@@ -10442,12 +10444,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;
-- 
1.8.3.1

