diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
new file mode 100755
index 2ab723d..990ad17
*** a/src/backend/access/heap/pruneheap.c
--- b/src/backend/access/heap/pruneheap.c
*************** heap_page_prune_opt(Relation relation, B
*** 88,95 ****
  	 * We can't write WAL in recovery mode, so there's no point trying to
  	 * clean the page. The master will likely issue a cleaning WAL record soon
  	 * anyway, so this is no particular loss.
  	 */
! 	if (RecoveryInProgress())
  		return;
  
  	/*
--- 88,99 ----
  	 * We can't write WAL in recovery mode, so there's no point trying to
  	 * clean the page. The master will likely issue a cleaning WAL record soon
  	 * anyway, so this is no particular loss.
+ 	 *
+ 	 * RecoveryMightBeInProgress() may indicate that we recovery is still in
+ 	 * progress when in fact we are not as it specifically is designed to
+ 	 * avoid the spinlock guarding xlogctl.
  	 */
! 	if (RecoveryMightBeInProgress())
  		return;
  
  	/*
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
new file mode 100755
index 959f423..652b16a
*** a/src/backend/access/transam/xlog.c
--- b/src/backend/access/transam/xlog.c
*************** RecoveryInProgress(void)
*** 6241,6246 ****
--- 6241,6276 ----
  }
  
  /*
+  * Is the system possibly in recovery?
+  *
+  * Unlike testing InRecovery, this works in any process that's connected to
+  * shared memory.  Also, this routine intentionally checks the shared
+  * recovery in progress flag without taking a proper lock; therefore it's
+  * very dangerous to call this routine unless you can handle the case (or
+  * don't care) of being told the system is in recover when it is not.
+  *
+  */
+ bool
+ RecoveryMightBeInProgress(void)
+ {
+ 	/*
+ 	 * We check shared state each time only until we leave recovery mode. We
+ 	 * can't re-enter recovery, so there's no need to keep checking after the
+ 	 * shared variable has once been seen false.
+ 	 */
+ 	if (!LocalRecoveryInProgress)
+ 		return false;
+ 	else
+ 	{
+ 		/* use volatile pointer to prevent code rearrangement */
+ 		volatile XLogCtlData *xlogctl = XLogCtl;
+ 
+ 		/* Intentionally query xlogctl without spinlocking! */
+ 		return  xlogctl->SharedRecoveryInProgress;
+ 	}
+ }
+ 
+ /*
   * Is HotStandby active yet? This is only important in special backends
   * since normal backends won't ever be able to connect until this returns
   * true. Postmaster knows this by way of signal, not via shared memory.
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
new file mode 100755
index f8f06c1..6339655
*** a/src/include/access/xlog.h
--- b/src/include/access/xlog.h
*************** extern void xlog_desc(StringInfo buf, ui
*** 282,287 ****
--- 282,288 ----
  extern void issue_xlog_fsync(int fd, XLogSegNo segno);
  
  extern bool RecoveryInProgress(void);
+ extern bool RecoveryMightBeInProgress(void);
  extern bool HotStandbyActive(void);
  extern bool XLogInsertAllowed(void);
  extern void GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream);
