diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c
index 87e8366642..53d6222775 100644
--- a/src/backend/access/gin/ginxlog.c
+++ b/src/backend/access/gin/ginxlog.c
@@ -772,16 +772,20 @@ gin_redo(XLogReaderState *record)
 }
 
 void
-gin_xlog_startup(void)
+gin_xlog_startup(bool in_redo)
 {
+	if (!in_redo)
+		return;
 	opCtx = AllocSetContextCreate(CurrentMemoryContext,
 								  "GIN recovery temporary context",
 								  ALLOCSET_DEFAULT_SIZES);
 }
 
 void
-gin_xlog_cleanup(void)
+gin_xlog_cleanup(bool in_redo)
 {
+	if (!in_redo)
+		return;
 	MemoryContextDelete(opCtx);
 	opCtx = NULL;
 }
diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c
index df70f906b4..49681109f2 100644
--- a/src/backend/access/gist/gistxlog.c
+++ b/src/backend/access/gist/gistxlog.c
@@ -440,14 +440,18 @@ gist_redo(XLogReaderState *record)
 }
 
 void
-gist_xlog_startup(void)
+gist_xlog_startup(bool in_redo)
 {
+	if (!in_redo)
+		return;
 	opCtx = createTempGistContext();
 }
 
 void
-gist_xlog_cleanup(void)
+gist_xlog_cleanup(bool in_redo)
 {
+	if (!in_redo)
+		return;
 	MemoryContextDelete(opCtx);
 }
 
diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c
index f9186ca233..a0c5c6c4fa 100644
--- a/src/backend/access/nbtree/nbtxlog.c
+++ b/src/backend/access/nbtree/nbtxlog.c
@@ -1069,16 +1069,20 @@ btree_redo(XLogReaderState *record)
 }
 
 void
-btree_xlog_startup(void)
+btree_xlog_startup(bool in_redo)
 {
+	if (!in_redo)
+		return;
 	opCtx = AllocSetContextCreate(CurrentMemoryContext,
 								  "Btree recovery temporary context",
 								  ALLOCSET_DEFAULT_SIZES);
 }
 
 void
-btree_xlog_cleanup(void)
+btree_xlog_cleanup(bool in_redo)
 {
+	if (!in_redo)
+		return;
 	MemoryContextDelete(opCtx);
 	opCtx = NULL;
 }
diff --git a/src/backend/access/spgist/spgxlog.c b/src/backend/access/spgist/spgxlog.c
index b500b2cced..3e4e6ec939 100644
--- a/src/backend/access/spgist/spgxlog.c
+++ b/src/backend/access/spgist/spgxlog.c
@@ -977,16 +977,20 @@ spg_redo(XLogReaderState *record)
 }
 
 void
-spg_xlog_startup(void)
+spg_xlog_startup(bool in_redo)
 {
+	if (!in_redo)
+		return;
 	opCtx = AllocSetContextCreate(CurrentMemoryContext,
 								  "SP-GiST temporary context",
 								  ALLOCSET_DEFAULT_SIZES);
 }
 
 void
-spg_xlog_cleanup(void)
+spg_xlog_cleanup(bool in_redo)
 {
+	if (!in_redo)
+		return;
 	MemoryContextDelete(opCtx);
 	opCtx = NULL;
 }
diff --git a/src/backend/access/transam/rmgr.c b/src/backend/access/transam/rmgr.c
index e1d6ebbd3d..ddd9e04fdb 100644
--- a/src/backend/access/transam/rmgr.c
+++ b/src/backend/access/transam/rmgr.c
@@ -46,7 +46,7 @@ RmgrData RmgrTable[RM_MAX_ID + 1] = {
  * Start up all resource managers.
  */
 void
-RmgrStartup(void)
+RmgrStartup(bool in_redo)
 {
 	for (int rmid = 0; rmid <= RM_MAX_ID; rmid++)
 	{
@@ -54,7 +54,7 @@ RmgrStartup(void)
 			continue;
 
 		if (RmgrTable[rmid].rm_startup != NULL)
-			RmgrTable[rmid].rm_startup();
+			RmgrTable[rmid].rm_startup(in_redo);
 	}
 }
 
@@ -62,7 +62,7 @@ RmgrStartup(void)
  * Clean up all resource managers.
  */
 void
-RmgrCleanup(void)
+RmgrCleanup(bool in_redo)
 {
 	for (int rmid = 0; rmid <= RM_MAX_ID; rmid++)
 	{
@@ -70,7 +70,7 @@ RmgrCleanup(void)
 			continue;
 
 		if (RmgrTable[rmid].rm_cleanup != NULL)
-			RmgrTable[rmid].rm_cleanup();
+			RmgrTable[rmid].rm_cleanup(in_redo);
 	}
 }
 
diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c
index 39ef865ed9..008b439dd6 100644
--- a/src/backend/access/transam/xlogrecovery.c
+++ b/src/backend/access/transam/xlogrecovery.c
@@ -1626,16 +1626,17 @@ PerformWalRecovery(void)
 	}
 
 	if (record != NULL)
+		InRedo = true;
+
+	RmgrStartup(InRedo);
+
+	if (InRedo)
 	{
 		TimestampTz xtime;
 		PGRUsage	ru0;
 
 		pg_rusage_init(&ru0);
 
-		InRedo = true;
-
-		RmgrStartup();
-
 		ereport(LOG,
 				(errmsg("redo starts at %X/%X",
 						LSN_FORMAT_ARGS(xlogreader->ReadRecPtr))));
@@ -1771,8 +1772,6 @@ PerformWalRecovery(void)
 			}
 		}
 
-		RmgrCleanup();
-
 		ereport(LOG,
 				(errmsg("redo done at %X/%X system usage: %s",
 						LSN_FORMAT_ARGS(xlogreader->ReadRecPtr),
@@ -1782,8 +1781,6 @@ PerformWalRecovery(void)
 			ereport(LOG,
 					(errmsg("last completed transaction was at log time %s",
 							timestamptz_to_str(xtime))));
-
-		InRedo = false;
 	}
 	else
 	{
@@ -1792,6 +1789,9 @@ PerformWalRecovery(void)
 				(errmsg("redo is not required")));
 	}
 
+	RmgrCleanup(InRedo);
+	InRedo = false;
+
 	/*
 	 * This check is intentionally after the above log messages that indicate
 	 * how far recovery went.
diff --git a/src/include/access/ginxlog.h b/src/include/access/ginxlog.h
index 21de389d79..e4a91a8d6e 100644
--- a/src/include/access/ginxlog.h
+++ b/src/include/access/ginxlog.h
@@ -209,8 +209,8 @@ typedef struct ginxlogDeleteListPages
 extern void gin_redo(XLogReaderState *record);
 extern void gin_desc(StringInfo buf, XLogReaderState *record);
 extern const char *gin_identify(uint8 info);
-extern void gin_xlog_startup(void);
-extern void gin_xlog_cleanup(void);
+extern void gin_xlog_startup(bool in_redo);
+extern void gin_xlog_cleanup(bool in_redo);
 extern void gin_mask(char *pagedata, BlockNumber blkno);
 
 #endif							/* GINXLOG_H */
diff --git a/src/include/access/gistxlog.h b/src/include/access/gistxlog.h
index 4537e67eba..39f08a9611 100644
--- a/src/include/access/gistxlog.h
+++ b/src/include/access/gistxlog.h
@@ -107,8 +107,8 @@ typedef struct gistxlogPageReuse
 extern void gist_redo(XLogReaderState *record);
 extern void gist_desc(StringInfo buf, XLogReaderState *record);
 extern const char *gist_identify(uint8 info);
-extern void gist_xlog_startup(void);
-extern void gist_xlog_cleanup(void);
+extern void gist_xlog_startup(bool in_redo);
+extern void gist_xlog_cleanup(bool in_redo);
 extern void gist_mask(char *pagedata, BlockNumber blkno);
 
 #endif
diff --git a/src/include/access/nbtxlog.h b/src/include/access/nbtxlog.h
index de362d3cb9..f6d05de06d 100644
--- a/src/include/access/nbtxlog.h
+++ b/src/include/access/nbtxlog.h
@@ -344,8 +344,8 @@ typedef struct xl_btree_newroot
 extern void btree_redo(XLogReaderState *record);
 extern void btree_desc(StringInfo buf, XLogReaderState *record);
 extern const char *btree_identify(uint8 info);
-extern void btree_xlog_startup(void);
-extern void btree_xlog_cleanup(void);
+extern void btree_xlog_startup(bool in_redo);
+extern void btree_xlog_cleanup(bool in_redo);
 extern void btree_mask(char *pagedata, BlockNumber blkno);
 
 #endif							/* NBTXLOG_H */
diff --git a/src/include/access/spgxlog.h b/src/include/access/spgxlog.h
index 930ffdd4f7..592ddb1d89 100644
--- a/src/include/access/spgxlog.h
+++ b/src/include/access/spgxlog.h
@@ -250,8 +250,8 @@ typedef struct spgxlogVacuumRedirect
 extern void spg_redo(XLogReaderState *record);
 extern void spg_desc(StringInfo buf, XLogReaderState *record);
 extern const char *spg_identify(uint8 info);
-extern void spg_xlog_startup(void);
-extern void spg_xlog_cleanup(void);
+extern void spg_xlog_startup(bool in_redo);
+extern void spg_xlog_cleanup(bool in_redo);
 extern void spg_mask(char *pagedata, BlockNumber blkno);
 
 #endif							/* SPGXLOG_H */
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index fae0bef8f5..058b2ef020 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -313,16 +313,16 @@ typedef struct RmgrData
 	void		(*rm_redo) (XLogReaderState *record);
 	void		(*rm_desc) (StringInfo buf, XLogReaderState *record);
 	const char *(*rm_identify) (uint8 info);
-	void		(*rm_startup) (void);
-	void		(*rm_cleanup) (void);
+	void		(*rm_startup) (bool in_redo);
+	void		(*rm_cleanup) (bool in_redo);
 	void		(*rm_mask) (char *pagedata, BlockNumber blkno);
 	void		(*rm_decode) (struct LogicalDecodingContext *ctx,
 							  struct XLogRecordBuffer *buf);
 } RmgrData;
 
 extern PGDLLIMPORT RmgrData RmgrTable[];
-extern void RmgrStartup(void);
-extern void RmgrCleanup(void);
+extern void RmgrStartup(bool in_redo);
+extern void RmgrCleanup(bool in_redo);
 extern void RmgrNotFound(RmgrId rmid);
 extern void RegisterCustomRmgr(RmgrId rmid, RmgrData *rmgr);
 
