diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 47a6c4d..cff238e 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8049,6 +8049,9 @@ LocalSetXLogInsertAllowed(void)
 
 	/* Initialize as RecoveryInProgress() would do when switching state */
 	InitXLOGAccess();
+
+	/* Also initialize the working areas for constructing WAL records */
+	InitXLogInsert();
 }
 
 /*
@@ -8178,9 +8181,6 @@ InitXLOGAccess(void)
 	(void) GetRedoRecPtr();
 	/* Also update our copy of doPageWrites. */
 	doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites);
-
-	/* Also initialize the working areas for constructing WAL records */
-	InitXLogInsert();
 }
 
 /*
@@ -8582,11 +8582,11 @@ CreateCheckPoint(int flags)
 
 	/*
 	 * Initialize InitXLogInsert working areas before entering the critical
-	 * section.  Normally, this is done by the first call to
-	 * RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
-	 * an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
-	 * done below in a critical section, and InitXLogInsert cannot be called
-	 * in a critical section.
+	 * section.  Normally, this is done at backend startup or when calling
+	 * LocalSetXLogInsertAllowed(), but when creating an end-of-recovery
+	 * checkpoint, the LocalSetXLogInsertAllowed call is done below in a
+	 * critical section, and InitXLogInsert cannot be called in a critical
+	 * section.
 	 */
 	InitXLogInsert();
 
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 28ff2f0..d81bf3e 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -441,17 +441,24 @@ AuxiliaryProcessMain(int argc, char *argv[])
 
 		case BgWriterProcess:
 			/* don't set signals, bgwriter has its own agenda */
+
+			/* Initialize the working areas for constructing WAL records. */
+			InitXLogInsert();
 			BackgroundWriterMain();
 			proc_exit(1);		/* should never return */
 
 		case CheckpointerProcess:
 			/* don't set signals, checkpointer has its own agenda */
+
+			/* Initialize the working areas for constructing WAL records. */
+			InitXLogInsert();
 			CheckpointerMain();
 			proc_exit(1);		/* should never return */
 
 		case WalWriterProcess:
 			/* don't set signals, walwriter has its own agenda */
 			InitXLOGAccess();
+			InitXLogInsert();
 			WalWriterMain();
 			proc_exit(1);		/* should never return */
 
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index d8f45b3..8db377c 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -619,6 +619,15 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 	if (IsUnderPostmaster)
 	{
 		/*
+		 * Initialize the working areas for constructing WAL records.
+		 * This is done even for a standby instance to avoid initialization
+		 * of this machinery after a promotion, which could happen in a
+		 * critical section and InitXLogInsert() cannot be called in such
+		 * a code path.
+		 */
+		InitXLogInsert();
+
+		/*
 		 * The postmaster already started the XLOG machinery, but we need to
 		 * call InitXLOGAccess(), if the system isn't in hot-standby mode.
 		 * This is handled by calling RecoveryInProgress and ignoring the
