diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c
index 52922dae4ec34d8b4a112438084dce26fff164cb..0c178c55c87247f651373bdc80a0f739a6f3c128 100644
--- a/src/backend/access/transam/xlogarchive.c
+++ b/src/backend/access/transam/xlogarchive.c
@@ -473,6 +473,12 @@ KeepFileRestoredFromArchive(char *path, char *xlogfname)
 				 errmsg("could not rename file \"%s\" to \"%s\": %m",
 						path, xlogfpath)));
 
+	/*
+	 * Create .done file forcibly to prevent the restored segment from
+	 * being archived again later.
+	 */
+	XLogArchiveForceDone(xlogfname);
+
 	/*
 	 * If the existing file was replaced, since walsenders might have it
 	 * open, request them to reload a currently-open segment. This is only
@@ -544,6 +550,59 @@ XLogArchiveNotifySeg(XLogSegNo segno)
 	XLogArchiveNotify(xlog);
 }
 
+/*
+ * XLogArchiveForceDone
+ *
+ * Emit notification forcibly that an XLOG segment file has been successfully
+ * archived, by creating <XLOG>.done regardless of whether <XLOG>.ready
+ * exists or not.
+ */
+void
+XLogArchiveForceDone(const char *xlog)
+{
+	char		archiveReady[MAXPGPATH];
+	char		archiveDone[MAXPGPATH];
+	struct stat stat_buf;
+	FILE	   *fd;
+
+	/* Exit if already known done */
+	StatusFilePath(archiveDone, xlog, ".done");
+	if (stat(archiveDone, &stat_buf) == 0)
+		return;
+
+	/* If .ready exists, rename it to .done */
+	StatusFilePath(archiveReady, xlog, ".ready");
+	if (stat(archiveReady, &stat_buf) == 0)
+	{
+		if (rename(archiveReady, archiveDone) < 0)
+			ereport(WARNING,
+					(errcode_for_file_access(),
+					 errmsg("could not rename file \"%s\" to \"%s\": %m",
+							archiveReady, archiveDone)));
+
+		return;
+	}
+
+	/* insert an otherwise empty file called <XLOG>.done */
+	fd = AllocateFile(archiveDone, "w");
+	if (fd == NULL)
+	{
+		ereport(LOG,
+				(errcode_for_file_access(),
+				 errmsg("could not create archive status file \"%s\": %m",
+						archiveDone)));
+		return;
+	}
+	if (FreeFile(fd))
+	{
+		ereport(LOG,
+				(errcode_for_file_access(),
+				 errmsg("could not write archive status file \"%s\": %m",
+						archiveDone)));
+		return;
+	}
+}
+
 /*
  * XLogArchiveCheckDone
  *
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 37d5e0821edaed476272d44fe96caf88bd613e33..911a66ba887973721e0cf98e92c42637c8baf16b 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -83,7 +83,7 @@ walrcv_disconnect_type walrcv_disconnect = NULL;
 /*
  * These variables are used similarly to openLogFile/SegNo/Off,
  * but for walreceiver to write the XLOG. recvFileTLI is the TimeLineID
- * corresponding the filename of recvFile, used for error messages.
+ * corresponding the filename of recvFile.
  */
 static int	recvFile = -1;
 static TimeLineID	recvFileTLI = 0;
@@ -528,12 +528,21 @@ WalReceiverMain(void)
 		 */
 		if (recvFile >= 0)
 		{
+			char		xlogfname[MAXFNAMELEN];
+
 			XLogWalRcvFlush(false);
 			if (close(recvFile) != 0)
 				ereport(PANIC,
 						(errcode_for_file_access(),
 						 errmsg("could not close log segment %s: %m",
 								XLogFileNameP(recvFileTLI, recvSegNo))));
+
+			/*
+			 * Create .done file forcibly to prevent the streamed segment from
+			 * being archived later.
+			 */
+			XLogFileName(xlogfname, recvFileTLI, recvSegNo);
+			XLogArchiveForceDone(xlogfname);
 		}
 		recvFile = -1;
 
@@ -865,6 +874,8 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr)
 			 */
 			if (recvFile >= 0)
 			{
+				char		xlogfname[MAXFNAMELEN];
+
 				XLogWalRcvFlush(false);
 
 				/*
@@ -877,6 +888,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 streamed segment from
+				 * being archived later.
+				 */
+				XLogFileName(xlogfname, recvFileTLI, recvSegNo);
+				XLogArchiveForceDone(xlogfname);
 			}
 			recvFile = -1;
 
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 16b53e37260b8abe2ec0ef4266bd71150a253f7a..c996c3c3ad867b8678a6971d4bfbc0d00231764f 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -278,6 +278,7 @@ extern void ExecuteRecoveryCommand(char *command, char *commandName,
 extern void KeepFileRestoredFromArchive(char  *path, char *xlogfname);
 extern void XLogArchiveNotify(const char *xlog);
 extern void XLogArchiveNotifySeg(XLogSegNo segno);
+extern void XLogArchiveForceDone(const char *xlog);
 extern bool XLogArchiveCheckDone(const char *xlog);
 extern bool XLogArchiveIsBusy(const char *xlog);
 extern void XLogArchiveCleanup(const char *xlog);