*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
***************
*** 60,67 ****
  
  
  /* File path names (all relative to $PGDATA) */
- #define BACKUP_LABEL_FILE		"backup_label"
- #define BACKUP_LABEL_OLD		"backup_label.old"
  #define RECOVERY_COMMAND_FILE	"recovery.conf"
  #define RECOVERY_COMMAND_DONE	"recovery.done"
  
--- 60,65 ----
***************
*** 339,344 **** typedef struct XLogCtlInsert
--- 337,351 ----
  	char	   *currpos;		/* current insertion point in cache */
  	XLogRecPtr	RedoRecPtr;		/* current redo point for insertions */
  	bool		forcePageWrites;	/* forcing full-page writes for PITR? */
+ 
+ 	/*
+ 	 * exclusiveBackup is true if a backup started with pg_start_backup() is
+ 	 * in progress, and nonExclusiveBackups is a counter indicating the number
+ 	 * of streaming base backups currently in progress. forcePageWrites is
+ 	 * set to true, when either of these is non-zero.
+ 	 */
+ 	bool		exclusiveBackup;
+ 	int			nonExclusiveBackups;
  } XLogCtlInsert;
  
  /*
***************
*** 8352,8367 **** pg_start_backup(PG_FUNCTION_ARGS)
  
  	backupidstr = text_to_cstring(backupid);
  
! 	startpoint = do_pg_start_backup(backupidstr, fast);
  
  	snprintf(startxlogstr, sizeof(startxlogstr), "%X/%X",
  			 startpoint.xlogid, startpoint.xrecoff);
  	PG_RETURN_TEXT_P(cstring_to_text(startxlogstr));
  }
  
  XLogRecPtr
! do_pg_start_backup(const char *backupidstr, bool fast)
  {
  	XLogRecPtr	checkpointloc;
  	XLogRecPtr	startpoint;
  	pg_time_t	stamp_time;
--- 8359,8396 ----
  
  	backupidstr = text_to_cstring(backupid);
  
! 	startpoint = do_pg_start_backup(backupidstr, fast, NULL);
  
  	snprintf(startxlogstr, sizeof(startxlogstr), "%X/%X",
  			 startpoint.xlogid, startpoint.xrecoff);
  	PG_RETURN_TEXT_P(cstring_to_text(startxlogstr));
  }
  
+ /*
+  * do_pg_start_backup is the workhorse of the user-visible pg_start_backup()
+  * function. It creates the necessary starting checkpoint and constructs the
+  * backup label file.
+  * 
+  * There are two kind of backups: exclusive and non-exclusive. An exclusive
+  * backup is started with pg_start_backup(), and there can be only one active
+  * at a time. The backup label file of an exclusive backup is written to
+  * $PGDATA/backup_label, and it is removed by pg_stop_backup().
+  *
+  * A non-exclusive backup is used for the streaming base backups (see
+  * src/backend/replication/basebackup.c). The difference to exclusive backups
+  * is that the backup label file is not written to disk. Instead, its would-be
+  * contents are returned in *labelfile, and the caller is responsible for
+  * including it in the backup archive as 'backup_label'. There can be many
+  * non-exclusive backups active at the same time, and they don't conflict
+  * with an exclusive backup either.
+  *
+  * Every successfully started non-exclusive backup must be stopped by calling
+  * do_pg_stop_backup() or do_pg_abort_backup().
+  */
  XLogRecPtr
! do_pg_start_backup(const char *backupidstr, bool fast, char **labelfile)
  {
+ 	bool		exclusive = (labelfile == NULL);
  	XLogRecPtr	checkpointloc;
  	XLogRecPtr	startpoint;
  	pg_time_t	stamp_time;
***************
*** 8371,8381 **** do_pg_start_backup(const char *backupidstr, bool fast)
  	uint32		_logSeg;
  	struct stat stat_buf;
  	FILE	   *fp;
  
! 	if (!superuser() && !is_authenticated_user_replication_role())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
! 				 errmsg("must be superuser or replication role to run a backup")));
  
  	if (RecoveryInProgress())
  		ereport(ERROR,
--- 8400,8411 ----
  	uint32		_logSeg;
  	struct stat stat_buf;
  	FILE	   *fp;
+ 	StringInfoData labelfbuf;
  
! 	if (exclusive && !superuser())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
! 				 errmsg("must be superuser to run a backup")));
  
  	if (RecoveryInProgress())
  		ereport(ERROR,
***************
*** 8389,8394 **** do_pg_start_backup(const char *backupidstr, bool fast)
--- 8419,8430 ----
  			  errmsg("WAL level not sufficient for making an online backup"),
  				 errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start.")));
  
+ 	if (strlen(backupidstr) > MAXPGPATH)
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 				 errmsg("backup label too long (max %d bytes)",
+ 						MAXPGPATH)));
+ 
  	/*
  	 * Mark backup active in shared memory.  We must do full-page WAL writes
  	 * during an on-line backup even if not doing so at other times, because
***************
*** 8407,8420 **** do_pg_start_backup(const char *backupidstr, bool fast)
  	 * ensure adequate interlocking against XLogInsert().
  	 */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
! 	if (XLogCtl->Insert.forcePageWrites)
  	{
! 		LWLockRelease(WALInsertLock);
! 		ereport(ERROR,
! 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
! 				 errmsg("a backup is already in progress"),
! 				 errhint("Run pg_stop_backup() and try again.")));
  	}
  	XLogCtl->Insert.forcePageWrites = true;
  	LWLockRelease(WALInsertLock);
  
--- 8443,8462 ----
  	 * ensure adequate interlocking against XLogInsert().
  	 */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
! 	if (exclusive)
  	{
! 		if (XLogCtl->Insert.exclusiveBackup)
! 		{
! 			LWLockRelease(WALInsertLock);
! 			ereport(ERROR,
! 					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
! 					 errmsg("a backup is already in progress"),
! 					 errhint("Run pg_stop_backup() and try again.")));
! 		}
! 		XLogCtl->Insert.exclusiveBackup = true;
  	}
+ 	else
+ 		XLogCtl->Insert.nonExclusiveBackups++;
  	XLogCtl->Insert.forcePageWrites = true;
  	LWLockRelease(WALInsertLock);
  
***************
*** 8432,8438 **** do_pg_start_backup(const char *backupidstr, bool fast)
  	RequestXLogSwitch();
  
  	/* Ensure we release forcePageWrites if fail below */
! 	PG_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) 0);
  	{
  		/*
  		 * Force a CHECKPOINT.	Aside from being necessary to prevent torn
--- 8474,8480 ----
  	RequestXLogSwitch();
  
  	/* Ensure we release forcePageWrites if fail below */
! 	PG_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) BoolGetDatum(exclusive));
  	{
  		/*
  		 * Force a CHECKPOINT.	Aside from being necessary to prevent torn
***************
*** 8459,8512 **** do_pg_start_backup(const char *backupidstr, bool fast)
  		XLByteToSeg(startpoint, _logId, _logSeg);
  		XLogFileName(xlogfilename, ThisTimeLineID, _logId, _logSeg);
  
  		/* Use the log timezone here, not the session timezone */
  		stamp_time = (pg_time_t) time(NULL);
  		pg_strftime(strfbuf, sizeof(strfbuf),
  					"%Y-%m-%d %H:%M:%S %Z",
  					pg_localtime(&stamp_time, log_timezone));
  
  		/*
! 		 * Check for existing backup label --- implies a backup is already
! 		 * running.  (XXX given that we checked forcePageWrites above, maybe
! 		 * it would be OK to just unlink any such label file?)
  		 */
! 		if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
  		{
! 			if (errno != ENOENT)
  				ereport(ERROR,
  						(errcode_for_file_access(),
! 						 errmsg("could not stat file \"%s\": %m",
  								BACKUP_LABEL_FILE)));
  		}
  		else
! 			ereport(ERROR,
! 					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
! 					 errmsg("a backup is already in progress"),
! 					 errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
! 							 BACKUP_LABEL_FILE)));
! 
! 		/*
! 		 * Okay, write the file
! 		 */
! 		fp = AllocateFile(BACKUP_LABEL_FILE, "w");
! 		if (!fp)
! 			ereport(ERROR,
! 					(errcode_for_file_access(),
! 					 errmsg("could not create file \"%s\": %m",
! 							BACKUP_LABEL_FILE)));
! 		fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
! 				startpoint.xlogid, startpoint.xrecoff, xlogfilename);
! 		fprintf(fp, "CHECKPOINT LOCATION: %X/%X\n",
! 				checkpointloc.xlogid, checkpointloc.xrecoff);
! 		fprintf(fp, "START TIME: %s\n", strfbuf);
! 		fprintf(fp, "LABEL: %s\n", backupidstr);
! 		if (fflush(fp) || ferror(fp) || FreeFile(fp))
! 			ereport(ERROR,
! 					(errcode_for_file_access(),
! 					 errmsg("could not write file \"%s\": %m",
! 							BACKUP_LABEL_FILE)));
  	}
! 	PG_END_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) 0);
  
  	/*
  	 * We're done.  As a convenience, return the starting WAL location.
--- 8501,8567 ----
  		XLByteToSeg(startpoint, _logId, _logSeg);
  		XLogFileName(xlogfilename, ThisTimeLineID, _logId, _logSeg);
  
+ 		/*
+ 		 * Construct backup label file 
+ 		 */
+ 		initStringInfo(&labelfbuf);
+ 
  		/* Use the log timezone here, not the session timezone */
  		stamp_time = (pg_time_t) time(NULL);
  		pg_strftime(strfbuf, sizeof(strfbuf),
  					"%Y-%m-%d %H:%M:%S %Z",
  					pg_localtime(&stamp_time, log_timezone));
+ 		appendStringInfo(&labelfbuf, "START WAL LOCATION: %X/%X (file %s)\n",
+ 						 startpoint.xlogid, startpoint.xrecoff, xlogfilename);
+ 		appendStringInfo(&labelfbuf, "CHECKPOINT LOCATION: %X/%X\n",
+ 						 checkpointloc.xlogid, checkpointloc.xrecoff);
+ 		appendStringInfo(&labelfbuf, "START TIME: %s\n", strfbuf);
+ 		appendStringInfo(&labelfbuf, "LABEL: %s\n", backupidstr);
  
  		/*
! 		 * Okay, write the file, or return its contents to caller.
  		 */
! 		if (exclusive)
  		{
! 			/*
! 			 * Check for existing backup label --- implies a backup is already
! 			 * running.  (XXX given that we checked exclusiveBackup above, maybe
! 			 * it would be OK to just unlink any such label file?)
! 			 */
! 			if (stat(BACKUP_LABEL_FILE, &stat_buf) != 0)
! 			{
! 				if (errno != ENOENT)
! 					ereport(ERROR,
! 							(errcode_for_file_access(),
! 							 errmsg("could not stat file \"%s\": %m",
! 									BACKUP_LABEL_FILE)));
! 			}
! 			else
! 				ereport(ERROR,
! 						(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
! 						 errmsg("a backup is already in progress"),
! 						 errhint("If you're sure there is no backup in progress, remove file \"%s\" and try again.",
! 								 BACKUP_LABEL_FILE)));
! 
! 			fp = AllocateFile(BACKUP_LABEL_FILE, "w");
! 
! 			if (!fp)
  				ereport(ERROR,
  						(errcode_for_file_access(),
! 						 errmsg("could not create file \"%s\": %m",
  								BACKUP_LABEL_FILE)));
+ 			fwrite(labelfbuf.data, labelfbuf.len, 1, fp);
+ 			if (fflush(fp) || ferror(fp) || FreeFile(fp))
+ 				ereport(ERROR,
+ 						(errcode_for_file_access(),
+ 						 errmsg("could not write file \"%s\": %m",
+ 								BACKUP_LABEL_FILE)));
+ 			pfree(labelfbuf.data);
  		}
  		else
! 			*labelfile = labelfbuf.data;
  	}
! 	PG_END_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) BoolGetDatum(exclusive));
  
  	/*
  	 * We're done.  As a convenience, return the starting WAL location.
***************
*** 8518,8526 **** do_pg_start_backup(const char *backupidstr, bool fast)
  static void
  pg_start_backup_callback(int code, Datum arg)
  {
! 	/* Turn off forcePageWrites on failure */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
! 	XLogCtl->Insert.forcePageWrites = false;
  	LWLockRelease(WALInsertLock);
  }
  
--- 8573,8592 ----
  static void
  pg_start_backup_callback(int code, Datum arg)
  {
! 	bool exclusive = DatumGetBool(arg);
! 
! 	/* Update backup counters and forcePageWrites on failure */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
! 	if (exclusive)
! 	{
! 		Assert(XLogCtl->Insert.exclusiveBackup);
! 		XLogCtl->Insert.exclusiveBackup = false;
! 	}
! 	else
! 		XLogCtl->Insert.nonExclusiveBackups--;
! 
! 	if (!XLogCtl->Insert.exclusiveBackup && XLogCtl->Insert.nonExclusiveBackups == 0)
! 		XLogCtl->Insert.forcePageWrites = false;
  	LWLockRelease(WALInsertLock);
  }
  
***************
*** 8543,8558 **** pg_stop_backup(PG_FUNCTION_ARGS)
  	XLogRecPtr	stoppoint;
  	char		stopxlogstr[MAXFNAMELEN];
  
! 	stoppoint = do_pg_stop_backup();
  
  	snprintf(stopxlogstr, sizeof(stopxlogstr), "%X/%X",
  			 stoppoint.xlogid, stoppoint.xrecoff);
  	PG_RETURN_TEXT_P(cstring_to_text(stopxlogstr));
  }
  
  XLogRecPtr
! do_pg_stop_backup(void)
  {
  	XLogRecPtr	startpoint;
  	XLogRecPtr	stoppoint;
  	XLogRecData rdata;
--- 8609,8632 ----
  	XLogRecPtr	stoppoint;
  	char		stopxlogstr[MAXFNAMELEN];
  
! 	stoppoint = do_pg_stop_backup(NULL);
  
  	snprintf(stopxlogstr, sizeof(stopxlogstr), "%X/%X",
  			 stoppoint.xlogid, stoppoint.xrecoff);
  	PG_RETURN_TEXT_P(cstring_to_text(stopxlogstr));
  }
  
+ /*
+  * do_pg_start_backup is the workhorse of the user-visible pg_stop_backup()
+  * function.
+ 
+  * If labelfile is NULL, this stops an exclusive backup. Otherwise this stops
+  * the non-exclusive backup specified by 'labelfile'.
+  */
  XLogRecPtr
! do_pg_stop_backup(char *labelfile)
  {
+ 	bool		exclusive = (labelfile == NULL);
  	XLogRecPtr	startpoint;
  	XLogRecPtr	stoppoint;
  	XLogRecData rdata;
***************
*** 8568,8582 **** do_pg_stop_backup(void)
  	FILE	   *lfp;
  	FILE	   *fp;
  	char		ch;
- 	int			ich;
  	int			seconds_before_warning;
  	int			waits = 0;
  	bool		reported_waiting = false;
  
! 	if (!superuser() && !is_authenticated_user_replication_role())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
! 				 (errmsg("must be superuser or replication role to run a backup"))));
  
  	if (RecoveryInProgress())
  		ereport(ERROR,
--- 8642,8656 ----
  	FILE	   *lfp;
  	FILE	   *fp;
  	char		ch;
  	int			seconds_before_warning;
  	int			waits = 0;
  	bool		reported_waiting = false;
+ 	char	   *remaining;
  
! 	if (exclusive && !superuser())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
! 				 errmsg("must be superuser to run a backup")));
  
  	if (RecoveryInProgress())
  		ereport(ERROR,
***************
*** 8591,8628 **** do_pg_stop_backup(void)
  				 errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start.")));
  
  	/*
! 	 * OK to clear forcePageWrites
  	 */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
! 	XLogCtl->Insert.forcePageWrites = false;
  	LWLockRelease(WALInsertLock);
  
! 	/*
! 	 * Open the existing label file
! 	 */
! 	lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
! 	if (!lfp)
  	{
! 		if (errno != ENOENT)
  			ereport(ERROR,
  					(errcode_for_file_access(),
  					 errmsg("could not read file \"%s\": %m",
  							BACKUP_LABEL_FILE)));
! 		ereport(ERROR,
! 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
! 				 errmsg("a backup is not in progress")));
  	}
  
  	/*
  	 * Read and parse the START WAL LOCATION line (this code is pretty crude,
  	 * but we are not expecting any variability in the file format).
  	 */
! 	if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %24s)%c",
  			   &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename,
  			   &ch) != 4 || ch != '\n')
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  				 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
  
  	/*
  	 * Write the backup-end xlog record
--- 8665,8749 ----
  				 errhint("wal_level must be set to \"archive\" or \"hot_standby\" at server start.")));
  
  	/*
! 	 * OK to update backup counters and forcePageWrites
  	 */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
! 	if (exclusive)
! 		XLogCtl->Insert.exclusiveBackup = false;
! 	else
! 	{
! 		/*
! 		 * The user-visible pg_start/stop_backup() functions that operate on
! 		 * exclusive backups can be called at any time, but for non-exclusive
! 		 * backups, it is expected that each do_pg_start_backup() call is
! 		 * matched by exactly one do_pg_stop_backup() call.
! 		 */
! 		Assert(XLogCtl->Insert.nonExclusiveBackups > 0);
! 		XLogCtl->Insert.nonExclusiveBackups--;
! 	}
! 
! 	if (!XLogCtl->Insert.exclusiveBackup && XLogCtl->Insert.nonExclusiveBackups == 0)
! 		XLogCtl->Insert.forcePageWrites = false;
  	LWLockRelease(WALInsertLock);
  
! 	if (exclusive)
  	{
! 		/*
! 		 * Read the existing label file into memory.
! 		 */
! 		struct	stat statbuf;
! 		int		r;
! 
! 		if (stat(BACKUP_LABEL_FILE, &statbuf))
! 		{
! 			if (errno != ENOENT)
! 				ereport(ERROR,
! 						(errcode_for_file_access(),
! 						 errmsg("could not stat file \"%s\": %m",
! 								BACKUP_LABEL_FILE)));
! 			ereport(ERROR,
! 					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
! 					 errmsg("a backup is not in progress")));
! 		}
! 
! 		lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
! 		if (!lfp)
! 		{
  			ereport(ERROR,
  					(errcode_for_file_access(),
  					 errmsg("could not read file \"%s\": %m",
  							BACKUP_LABEL_FILE)));
! 		}
! 		labelfile = palloc(statbuf.st_size + 1);
! 		r = fread(labelfile, statbuf.st_size, 1, lfp);
! 		labelfile[statbuf.st_size] = '\0';
! 
! 		/*
! 		 * Close and remove the backup label file
! 		 */
! 		if (r != 1 || ferror(lfp) || FreeFile(lfp))
! 			ereport(ERROR,
! 					(errcode_for_file_access(),
! 					 errmsg("could not read file \"%s\": %m",
! 							BACKUP_LABEL_FILE)));
! 		if (unlink(BACKUP_LABEL_FILE) != 0)
! 			ereport(ERROR,
! 					(errcode_for_file_access(),
! 					 errmsg("could not remove file \"%s\": %m",
! 							BACKUP_LABEL_FILE)));
  	}
  
  	/*
  	 * Read and parse the START WAL LOCATION line (this code is pretty crude,
  	 * but we are not expecting any variability in the file format).
  	 */
! 	if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c",
  			   &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename,
  			   &ch) != 4 || ch != '\n')
  		ereport(ERROR,
  				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
  				 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
+ 	remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */
  
  	/*
  	 * Write the backup-end xlog record
***************
*** 8665,8672 **** do_pg_stop_backup(void)
  	fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
  			stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename);
  	/* transfer remaining lines from label to history file */
! 	while ((ich = fgetc(lfp)) != EOF)
! 		fputc(ich, fp);
  	fprintf(fp, "STOP TIME: %s\n", strfbuf);
  	if (fflush(fp) || ferror(fp) || FreeFile(fp))
  		ereport(ERROR,
--- 8786,8792 ----
  	fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
  			stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename);
  	/* transfer remaining lines from label to history file */
! 	fprintf(fp, "%s", remaining);
  	fprintf(fp, "STOP TIME: %s\n", strfbuf);
  	if (fflush(fp) || ferror(fp) || FreeFile(fp))
  		ereport(ERROR,
***************
*** 8675,8694 **** do_pg_stop_backup(void)
  						histfilepath)));
  
  	/*
- 	 * Close and remove the backup label file
- 	 */
- 	if (ferror(lfp) || FreeFile(lfp))
- 		ereport(ERROR,
- 				(errcode_for_file_access(),
- 				 errmsg("could not read file \"%s\": %m",
- 						BACKUP_LABEL_FILE)));
- 	if (unlink(BACKUP_LABEL_FILE) != 0)
- 		ereport(ERROR,
- 				(errcode_for_file_access(),
- 				 errmsg("could not remove file \"%s\": %m",
- 						BACKUP_LABEL_FILE)));
- 
- 	/*
  	 * Clean out any no-longer-needed history files.  As a side effect, this
  	 * will post a .ready file for the newly created history file, notifying
  	 * the archiver that history file may be archived immediately.
--- 8795,8800 ----
***************
*** 8769,8796 **** do_pg_stop_backup(void)
  /*
   * do_pg_abort_backup: abort a running backup
   *
!  * This does just the most basic steps of pg_stop_backup(), by taking the
   * system out of backup mode, thus making it a lot more safe to call from
   * an error handler.
   */
  void
  do_pg_abort_backup(void)
  {
- 	/*
- 	 * OK to clear forcePageWrites
- 	 */
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
! 	XLogCtl->Insert.forcePageWrites = false;
! 	LWLockRelease(WALInsertLock);
  
! 	/*
! 	 * Remove backup label file
! 	 */
! 	if (unlink(BACKUP_LABEL_FILE) != 0)
! 		ereport(ERROR,
! 				(errcode_for_file_access(),
! 				 errmsg("could not remove file \"%s\": %m",
! 						BACKUP_LABEL_FILE)));
  }
  
  /*
--- 8875,8899 ----
  /*
   * do_pg_abort_backup: abort a running backup
   *
!  * This does just the most basic steps of do_pg_stop_backup(), by taking the
   * system out of backup mode, thus making it a lot more safe to call from
   * an error handler.
+  *
+  * NB: This is only for aborting a non-exclusive backup that doesn't write
+  * backup_label. A backup started with pg_stop_backup() needs to be finished
+  * with pg_stop_backup().
   */
  void
  do_pg_abort_backup(void)
  {
  	LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
! 	Assert(XLogCtl->Insert.nonExclusiveBackups > 0);
! 	XLogCtl->Insert.nonExclusiveBackups--;
  
! 	if (!XLogCtl->Insert.exclusiveBackup && XLogCtl->Insert.nonExclusiveBackups == 0)
! 		XLogCtl->Insert.forcePageWrites = false;
! 
! 	LWLockRelease(WALInsertLock);
  }
  
  /*
