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..365ea3f *** a/src/backend/access/transam/xlog.c --- b/src/backend/access/transam/xlog.c *************** RecoveryInProgress(void) *** 6241,6246 **** --- 6241,6278 ---- } /* + * 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! */ + LocalRecoveryInProgress = xlogctl->SharedRecoveryInProgress; + + return LocalRecoveryInProgress; + } + } + + /* * 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. *************** CreateCheckPoint(int flags) *** 6866,6872 **** XLogRecPtr curInsert; INSERT_RECPTR(curInsert, Insert, Insert->curridx); ! if (curInsert == ControlFile->checkPoint + MAXALIGN(SizeOfXLogRecord + sizeof(CheckPoint)) && ControlFile->checkPoint == ControlFile->checkPointCopy.redo) { --- 6898,6904 ---- XLogRecPtr curInsert; INSERT_RECPTR(curInsert, Insert, Insert->curridx); ! if (curInsert == ControlFile->checkPoint + MAXALIGN(SizeOfXLogRecord + sizeof(CheckPoint)) && ControlFile->checkPoint == ControlFile->checkPointCopy.redo) { 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);