diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 24165ab03e..1e5b49595b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -933,6 +933,7 @@ static void RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
 static void UpdateLastRemovedPtr(char *filename);
 static void ValidateXLOGDirectoryStructure(void);
 static void RegisterSegmentBoundary(XLogSegNo seg, XLogRecPtr pos);
+static void NotifySegmentsReadyForArchive(XLogRecPtr flushRecPtr);
 static void CleanupBackupHistory(void);
 static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force);
 static XLogRecord *ReadRecord(XLogReaderState *xlogreader,
@@ -1157,6 +1158,29 @@ XLogInsertRecord(XLogRecData *rdata,
 		 */
 	}
 
+	/*
+	 * Register our crossing the segment boundary if that occurred.  We
+	 * do this before WALInsertLockRelease() so that the record cannot be
+	 * flushed to disk prior to registering the boundary (which could cause
+	 * us to miss marking segments as ready for archive).
+	 *
+	 * Note that we do not use XLByteToPrevSeg() for determining the ending
+	 * segment.  This is so that a record that fits perfectly into the end
+	 * of the segment causes the segment to get marked ready for archival
+	 * immediately.
+	 */
+	if (XLogArchivingActive())
+	{
+		XLogSegNo StartSeg;
+		XLogSegNo EndSeg;
+
+		XLByteToSeg(StartPos, StartSeg, wal_segment_size);
+		XLByteToSeg(EndPos, EndSeg, wal_segment_size);
+
+		if (StartSeg != EndSeg)
+			RegisterSegmentBoundary(EndSeg, EndPos);
+	}
+
 	/*
 	 * Done! Let others know that we're finished.
 	 */
@@ -1167,51 +1191,16 @@ XLogInsertRecord(XLogRecData *rdata,
 	END_CRIT_SECTION();
 
 	/*
-	 * If we crossed page boundary, update LogwrtRqst.Write; if we crossed
-	 * segment boundary, register that and wake up walwriter.
+	 * If we crossed page boundary, update LogwrtRqst.Write.
 	 */
 	if (StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ)
 	{
-		XLogSegNo	StartSeg;
-		XLogSegNo	EndSeg;
-
-		XLByteToSeg(StartPos, StartSeg, wal_segment_size);
-		XLByteToSeg(EndPos, EndSeg, wal_segment_size);
-
-		/*
-		 * Register our crossing the segment boundary if that occurred.
-		 *
-		 * Note that we did not use XLByteToPrevSeg() for determining the
-		 * ending segment.  This is so that a record that fits perfectly into
-		 * the end of the segment causes the latter to get marked ready for
-		 * archival immediately.
-		 */
-		if (StartSeg != EndSeg && XLogArchivingActive())
-			RegisterSegmentBoundary(EndSeg, EndPos);
-
-		/*
-		 * Advance LogwrtRqst.Write so that it includes new block(s).
-		 *
-		 * We do this after registering the segment boundary so that the
-		 * comparison with the flushed pointer below can use the latest value
-		 * known globally.
-		 */
 		SpinLockAcquire(&XLogCtl->info_lck);
 		if (XLogCtl->LogwrtRqst.Write < EndPos)
 			XLogCtl->LogwrtRqst.Write = EndPos;
 		/* update local result copy while I have the chance */
 		LogwrtResult = XLogCtl->LogwrtResult;
 		SpinLockRelease(&XLogCtl->info_lck);
-
-		/*
-		 * There's a chance that the record was already flushed to disk and we
-		 * missed marking segments as ready for archive.  If this happens, we
-		 * nudge the WALWriter, which will take care of notifying segments as
-		 * needed.
-		 */
-		if (StartSeg != EndSeg && XLogArchivingActive() &&
-			LogwrtResult.Flush >= EndPos && ProcGlobal->walwriterLatch)
-			SetLatch(ProcGlobal->walwriterLatch);
 	}
 
 	/*
@@ -2720,6 +2709,9 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
 		WalSndWakeupRequest();
 
 		LogwrtResult.Flush = LogwrtResult.Write;
+
+		if (XLogArchivingActive())
+			NotifySegmentsReadyForArchive(LogwrtResult.Flush);
 	}
 
 	/*
@@ -2738,9 +2730,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible)
 			XLogCtl->LogwrtRqst.Flush = LogwrtResult.Flush;
 		SpinLockRelease(&XLogCtl->info_lck);
 	}
-
-	if (XLogArchivingActive())
-		NotifySegmentsReadyForArchive(LogwrtResult.Flush);
 }
 
 /*
@@ -4434,7 +4423,7 @@ RegisterSegmentBoundary(XLogSegNo seg, XLogRecPtr endpos)
  * Mark segments as ready for archival, given that it is safe to do so.
  * This function is idempotent.
  */
-void
+static void
 NotifySegmentsReadyForArchive(XLogRecPtr flushRecPtr)
 {
 	XLogSegNo	latest_boundary_seg;
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 6a1e16edc2..626fae8454 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -248,13 +248,6 @@ WalWriterMain(void)
 		/* Process any signals received recently */
 		HandleWalWriterInterrupts();
 
-		/*
-		 * Notify the archiver of any WAL segments that are ready.  We do this
-		 * here to handle a race condition where WAL is flushed to disk prior
-		 * to registering the segment boundary.
-		 */
-		NotifySegmentsReadyForArchive(GetFlushRecPtr());
-
 		/*
 		 * Do what we're here for; then, if XLogBackgroundFlush() found useful
 		 * work to do, reset hibernation counter.
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index 6b6ae81c2d..0a8ede700d 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -315,7 +315,6 @@ extern XLogRecPtr GetInsertRecPtr(void);
 extern XLogRecPtr GetFlushRecPtr(void);
 extern XLogRecPtr GetLastImportantRecPtr(void);
 extern void RemovePromoteSignalFiles(void);
-extern void NotifySegmentsReadyForArchive(XLogRecPtr flushRecPtr);
 
 extern bool PromoteIsTriggered(void);
 extern bool CheckPromoteSignal(void);
