diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index e71090f..437d74b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 
 #include "access/clog.h"
+#include "access/xlog.h"
 #include "access/multixact.h"
 #include "access/subtrans.h"
 #include "access/transam.h"
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 073ef8d..03d7f18 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -802,6 +802,7 @@ ExecOpenScanRelation(EState *estate, Index scanrelid)
 {
 	Oid			reloid;
 	LOCKMODE	lockmode;
+	Relation	rel;
 
 	/*
 	 * Determine the lock type we need.  First, scan to see if target relation
@@ -829,7 +830,15 @@ ExecOpenScanRelation(EState *estate, Index scanrelid)
 
 	/* OK, open the relation and acquire lock as needed */
 	reloid = getrelid(scanrelid, estate->es_range_table);
-	return heap_open(reloid, lockmode);
+	rel = heap_open(reloid, lockmode);
+
+	/* We can't scan temporary or unlogged relations during recovery. */
+	if (!RelationNeedsWAL(rel) && RecoveryInProgress())
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("cannot access temporary or unlogged relations during recovery")));
+
+	return rel;
 }
 
 /* ----------------------------------------------------------------
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index fd8ea45..2555d8f 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -106,7 +106,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 	 * must leave it zero for now to avoid bollixing the total_table_pages
 	 * calculation.
 	 */
-	if (!inhparent)
+	if (!inhparent && (RelationNeedsWAL(relation) || !RecoveryInProgress()))
 		estimate_rel_size(relation, rel->attr_widths - rel->min_attr,
 						  &rel->pages, &rel->tuples);
 
@@ -321,7 +321,10 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 			 */
 			if (info->indpred == NIL)
 			{
-				info->pages = RelationGetNumberOfBlocks(indexRelation);
+				if (RelationNeedsWAL(indexRelation) || !RecoveryInProgress())
+					info->pages = RelationGetNumberOfBlocks(indexRelation);
+				else
+					info->pages = 0;
 				info->tuples = rel->tuples;
 			}
 			else
@@ -374,8 +377,15 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
 		case RELKIND_RELATION:
 		case RELKIND_INDEX:
 		case RELKIND_TOASTVALUE:
-			/* it has storage, ok to call the smgr */
-			curpages = RelationGetNumberOfBlocks(rel);
+			/*
+			 * It has storage; we can call the smgr.  But not for temporary
+			 * or unlogged relations during recovery, when such relations
+			 * are not available.
+			 */
+			if (RelationNeedsWAL(rel) || !RecoveryInProgress())
+				curpages = RelationGetNumberOfBlocks(rel);
+			else
+				curpages = 0;
 
 			/*
 			 * HACK: if the relation has never yet been vacuumed, use a
