diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index cd30f15eba..704d8f3744 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -475,6 +475,16 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
 		if (progress)
 			pgstat_progress_update_param(PROGRESS_WAITFOR_DONE, i + 1);
 	}
+
+	/*
+	 * Take a snapshot of running transactions and write this to WAL.  With
+	 * this information, a standby is able to know that it should not access
+	 * too soon any information we expect to wait for with a concurrent build.
+	 *
+	 * Skip the log of this information if disabled.
+	 */
+	if (XLogStandbyInfoActive())
+		LogStandbySnapshot();
 }
 
 
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index 1543da6162..81f0e7c88c 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -974,6 +974,25 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress)
 		pgstat_progress_update_multi_param(3, index, values);
 	}
 
+	/*
+	 * Now that the wait is done, log a set of access exclusive locks on
+	 * the relation locktags we waited for.  This level of lock is higher
+	 * than what a standby should need to be able to look at the catalog
+	 * information of the objects involved.  This ensures to block any
+	 * attempt to the objects that it will until the transaction running
+	 * this routine is committed at recovery.
+	 */
+	foreach(lc, locktags)
+	{
+		LOCKTAG *locktag = lfirst(lc);
+
+		if (locktag->locktag_type != LOCKTAG_RELATION)
+			continue;
+
+		LogAccessExclusiveLock(locktag->locktag_field1,		/* dbId */
+							   locktag->locktag_field2);	/* relId */
+	}
+
 	list_free_deep(holders);
 }
 
