diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index efd0347..393315f 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -605,7 +605,6 @@ typedef struct xl_restore_point
 } xl_restore_point;
 
 
-static void XLogArchiveNotify(const char *xlog);
 static void XLogArchiveNotifySeg(XLogSegNo segno);
 static bool XLogArchiveCheckDone(const char *xlog);
 static bool XLogArchiveIsBusy(const char *xlog);
@@ -1280,23 +1279,63 @@ XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
 }
 
 /*
- * XLogArchiveNotify
+ * XLogSetArchiveStatus
  *
- * Create an archive notification file
+ * Create an archive notification file with given archive status
  *
  * The name of the notification file is the message that will be picked up
  * by the archiver, e.g. we write 0000000100000001000000C6.ready
  * and the archiver then knows to archive XLOGDIR/0000000100000001000000C6,
  * then when complete, rename it to 0000000100000001000000C6.done
  */
-static void
-XLogArchiveNotify(const char *xlog)
+void
+XLogSetArchiveStatus(const char *xlog, int archive_status)
 {
 	char		archiveStatusPath[MAXPGPATH];
+	struct stat stat_buf;
 	FILE	   *fd;
 
-	/* insert an otherwise empty file called <XLOG>.ready */
-	StatusFilePath(archiveStatusPath, xlog, ".ready");
+	switch (archive_status)
+	{
+		case XLOG_ARCHIVE_STATUS_READY:
+
+			/* If already marked READY then quick exit */
+			StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_READY);
+			if (stat(archiveStatusPath, &stat_buf) == 0)
+				return;
+
+			break;
+
+		case XLOG_ARCHIVE_STATUS_DONE:
+
+			/* If marked READY then rename to DONE */
+			StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_READY);
+			if (stat(archiveStatusPath, &stat_buf) == 0)
+			{
+				char	archiveStatusDone[MAXPGPATH];
+
+				StatusFilePath(archiveStatusDone, xlog, XLOG_ARCHIVE_STATUS_DONE);
+
+				if (rename(archiveStatusPath, archiveStatusDone) < 0)
+					ereport(WARNING,
+							(errcode_for_file_access(),
+							 errmsg("could not rename file \"%s\" to \"%s\": %m",
+									archiveStatusPath, archiveStatusDone)));
+				return;
+			}
+
+			/* If already marked DONE then exit */
+			StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_DONE);
+			if (stat(archiveStatusPath, &stat_buf) == 0)
+				return;
+
+			break;
+
+		default:
+			elog(ERROR, "invalud archive status");
+	}
+
+	/* insert an otherwise empty file with prefix that indicates archive_status */
 	fd = AllocateFile(archiveStatusPath, "w");
 	if (fd == NULL)
 	{
@@ -1315,13 +1354,15 @@ XLogArchiveNotify(const char *xlog)
 		return;
 	}
 
-	/* Notify archiver that it's got something to do */
-	if (IsUnderPostmaster)
+	/* Notify archiver that it's got something to do if .ready has been created */
+	if (IsUnderPostmaster && archive_status == XLOG_ARCHIVE_STATUS_READY)
 		SendPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER);
 }
 
 /*
  * Convenience routine to notify using segment number representation of filename
+ *
+ * This always creates XLOG_ARCHIVE_STATUS_READY
  */
 static void
 XLogArchiveNotifySeg(XLogSegNo segno)
@@ -1329,7 +1370,7 @@ XLogArchiveNotifySeg(XLogSegNo segno)
 	char		xlog[MAXFNAMELEN];
 
 	XLogFileName(xlog, ThisTimeLineID, segno);
-	XLogArchiveNotify(xlog);
+	XLogSetArchiveStatus(xlog, XLOG_ARCHIVE_STATUS_READY);
 }
 
 /*
@@ -1357,22 +1398,22 @@ XLogArchiveCheckDone(const char *xlog)
 		return true;
 
 	/* First check for .done --- this means archiver is done with it */
-	StatusFilePath(archiveStatusPath, xlog, ".done");
+	StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_DONE);
 	if (stat(archiveStatusPath, &stat_buf) == 0)
 		return true;
 
 	/* check for .ready --- this means archiver is still busy with it */
-	StatusFilePath(archiveStatusPath, xlog, ".ready");
+	StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_READY);
 	if (stat(archiveStatusPath, &stat_buf) == 0)
 		return false;
 
 	/* Race condition --- maybe archiver just finished, so recheck */
-	StatusFilePath(archiveStatusPath, xlog, ".done");
+	StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_DONE);
 	if (stat(archiveStatusPath, &stat_buf) == 0)
 		return true;
 
 	/* Retry creation of the .ready file */
-	XLogArchiveNotify(xlog);
+	XLogSetArchiveStatus(xlog, XLOG_ARCHIVE_STATUS_READY);
 	return false;
 }
 
@@ -1393,17 +1434,17 @@ XLogArchiveIsBusy(const char *xlog)
 	struct stat stat_buf;
 
 	/* First check for .done --- this means archiver is done with it */
-	StatusFilePath(archiveStatusPath, xlog, ".done");
+	StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_DONE);
 	if (stat(archiveStatusPath, &stat_buf) == 0)
 		return false;
 
 	/* check for .ready --- this means archiver is still busy with it */
-	StatusFilePath(archiveStatusPath, xlog, ".ready");
+	StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_READY);
 	if (stat(archiveStatusPath, &stat_buf) == 0)
 		return true;
 
 	/* Race condition --- maybe archiver just finished, so recheck */
-	StatusFilePath(archiveStatusPath, xlog, ".done");
+	StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_DONE);
 	if (stat(archiveStatusPath, &stat_buf) == 0)
 		return false;
 
@@ -1431,12 +1472,12 @@ XLogArchiveCleanup(const char *xlog)
 	char		archiveStatusPath[MAXPGPATH];
 
 	/* Remove the .done file */
-	StatusFilePath(archiveStatusPath, xlog, ".done");
+	StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_DONE);
 	unlink(archiveStatusPath);
 	/* should we complain about failure? */
 
 	/* Remove the .ready file if present --- normally it shouldn't be */
-	StatusFilePath(archiveStatusPath, xlog, ".ready");
+	StatusFilePath(archiveStatusPath, xlog, XLOG_ARCHIVE_STATUS_READY);
 	unlink(archiveStatusPath);
 	/* should we complain about failure? */
 }
@@ -2806,6 +2847,12 @@ XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli,
 							path, xlogfpath)));
 
 		/*
+		 * Create .done file forcibly to prevent the restored segment from
+		 * being archived again later.
+		 */
+		XLogSetArchiveStatus(xlogfname, XLOG_ARCHIVE_STATUS_DONE);
+
+		/*
 		 * If the existing segment was replaced, since walsenders might have
 		 * it open, request them to reload a currently-open segment.
 		 */
@@ -3573,7 +3620,7 @@ ValidateXLOGDirectoryStructure(void)
 
 /*
  * Remove previous backup history files.  This also retries creation of
- * .ready files for any backup history files for which XLogArchiveNotify
+ * .ready files for any backup history files for which XLogSetArchiveStatus
  * failed earlier.
  */
 static void
@@ -4669,7 +4716,7 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI,
 
 	/* The history file can be archived immediately. */
 	TLHistoryFileName(histfname, newTLI);
-	XLogArchiveNotify(histfname);
+	XLogSetArchiveStatus(histfname, XLOG_ARCHIVE_STATUS_READY);
 }
 
 /*
@@ -5611,7 +5658,7 @@ exitArchiveRecovery(TimeLineID endTLI, XLogSegNo endLogSegNo)
 		if (XLogArchivingActive())
 		{
 			XLogFileName(xlogpath, endTLI, endLogSegNo);
-			XLogArchiveNotify(xlogpath);
+			XLogSetArchiveStatus(xlogpath, XLOG_ARCHIVE_STATUS_READY);
 		}
 	}
 
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index d5d8be0..1a51e17 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -111,7 +111,6 @@ static void pgarch_MainLoop(void);
 static void pgarch_ArchiverCopyLoop(void);
 static bool pgarch_archiveXlog(char *xlog);
 static bool pgarch_readyXlog(char *xlog);
-static void pgarch_archiveDone(char *xlog);
 
 
 /* ------------------------------------------------------------
@@ -492,7 +491,7 @@ pgarch_ArchiverCopyLoop(void)
 			if (pgarch_archiveXlog(xlog))
 			{
 				/* successful */
-				pgarch_archiveDone(xlog);
+				XLogSetArchiveStatus(xlog, XLOG_ARCHIVE_STATUS_DONE);
 				break;			/* out of inner retry loop */
 			}
 			else
@@ -730,26 +729,3 @@ pgarch_readyXlog(char *xlog)
 	}
 	return found;
 }
-
-/*
- * pgarch_archiveDone
- *
- * Emit notification that an xlog file has been successfully archived.
- * We do this by renaming the status file from NNN.ready to NNN.done.
- * Eventually, a checkpoint process will notice this and delete both the
- * NNN.done file and the xlog file itself.
- */
-static void
-pgarch_archiveDone(char *xlog)
-{
-	char		rlogready[MAXPGPATH];
-	char		rlogdone[MAXPGPATH];
-
-	StatusFilePath(rlogready, xlog, ".ready");
-	StatusFilePath(rlogdone, xlog, ".done");
-	if (rename(rlogready, rlogdone) < 0)
-		ereport(WARNING,
-				(errcode_for_file_access(),
-				 errmsg("could not rename file \"%s\" to \"%s\": %m",
-						rlogready, rlogdone)));
-}
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index b0a8b19..9d689c2 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -505,6 +505,13 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
 							(errcode_for_file_access(),
 							 errmsg("could not close log segment %s: %m",
 									XLogFileNameP(recvFileTLI, recvSegNo))));
+
+				/*
+				 * Create .done file forcibly to prevent the restored segment from
+				 * being archived again later.
+				 */
+				XLogSetArchiveStatus(XLogFileNameP(recvFileTLI, recvSegNo),
+										XLOG_ARCHIVE_STATUS_DONE);
 			}
 			recvFile = -1;
 
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index b5bfb7b..78849ce 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -192,8 +192,14 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
 #define TLHistoryFilePath(path, tli)	\
 	snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli)
 
-#define StatusFilePath(path, xlog, suffix)	\
-	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix)
+#define XLOG_ARCHIVE_STATUS_INVALID	0
+#define XLOG_ARCHIVE_STATUS_READY	1
+#define XLOG_ARCHIVE_STATUS_DONE	2
+
+#define StatusFilePath(path, xlog, archive_status)	\
+	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, \
+		(archive_status == XLOG_ARCHIVE_STATUS_READY ? ".ready" : ".done"))
+
 
 #define BackupHistoryFileName(fname, tli, logSegNo, offset) \
 	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, \
@@ -230,6 +236,11 @@ extern pg_time_t GetLastSegSwitchTime(void);
 extern XLogRecPtr RequestXLogSwitch(void);
 
 /*
+ * Exported to support xlog archive status setting from WALReceiver/Archiver
+ */
+extern void XLogSetArchiveStatus(const char *xlog, int archive_status);
+
+/*
  * These aren't in xlog.h because I'd rather not include fmgr.h there.
  */
 extern Datum pg_start_backup(PG_FUNCTION_ARGS);
