diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 8243ea62d7834d79d07406ae3904eaf724dd6436..190d86b752990ab6b1f5d1af3992c6cb20e9989b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6530,6 +6530,12 @@ StartupXLOG(void)
 	XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch;
 	XLogCtl->ckptXid = checkPoint.nextXid;
 
+	/*
+	 * Startup MultiXact.  We need to do this early because we need its state
+	 * initialized because we attempt truncation during restartpoints.
+	 */
+	StartupMultiXact();
+
 	/*
 	 * We must replay WAL entries using the same TimeLineID they were created
 	 * under, so temporarily adopt the TLI indicated by the checkpoint (see
@@ -6696,8 +6702,9 @@ StartupXLOG(void)
 			ProcArrayInitRecovery(ShmemVariableCache->nextXid);
 
 			/*
-			 * Startup commit log and subtrans only. Other SLRUs are not
-			 * maintained during recovery and need not be started yet.
+			 * Startup commit log and subtrans only. MultiXact has already
+			 * been started up and other SLRUs are not maintained during
+			 * recovery and need not be started yet.
 			 */
 			StartupCLOG();
 			StartupSUBTRANS(oldestActiveXID);
@@ -7238,7 +7245,7 @@ StartupXLOG(void)
 	/*
 	 * Perform end of recovery actions for any SLRUs that need it.
 	 */
-	StartupMultiXact();
+	TrimMultiXact();
 	TrimCLOG();
 
 	/* Reload shared-memory state for prepared transactions */
diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h
index e20573d01fb834e32a8440c799c99d334a1b8ebc..7f46c3eeea4e8fa2db817cda50570650ce73979f 100644
--- a/src/include/access/multixact.h
+++ b/src/include/access/multixact.h
@@ -59,6 +59,7 @@ extern Size MultiXactShmemSize(void);
 extern void MultiXactShmemInit(void);
 extern void BootStrapMultiXact(void);
 extern void StartupMultiXact(void);
+extern void TrimMultiXact(void);
 extern void ShutdownMultiXact(void);
 extern void MultiXactGetCheckptMulti(bool is_shutdown,
 						 MultiXactId *nextMulti,