*** a/src/backend/access/transam/clog.c
--- b/src/backend/access/transam/clog.c
***************
*** 355,364 **** TransactionIdSetStatusBit(TransactionId xid, XidStatus status, XLogRecPtr lsn, i
  	/*
  	 * Update the group LSN if the transaction completion LSN is higher.
  	 *
! 	 * Note: lsn will be invalid when supplied during InRecovery processing,
! 	 * so we don't need to do anything special to avoid LSN updates during
! 	 * recovery. After recovery completes the next clog change will set the
! 	 * LSN correctly.
  	 */
  	if (!XLogRecPtrIsInvalid(lsn))
  	{
--- 355,364 ----
  	/*
  	 * Update the group LSN if the transaction completion LSN is higher.
  	 *
! 	 * Note: lsn will be invalid when supplied while we're performing
! 	 * recovery but hot standby is disabled, so we don't need to do
! 	 * anything special to avoid LSN updates in that case. After recovery
! 	 * completes the next clog change will set the LSN correctly.
  	 */
  	if (!XLogRecPtrIsInvalid(lsn))
  	{
*** a/src/backend/access/transam/xact.c
--- b/src/backend/access/transam/xact.c
***************
*** 4522,4530 **** xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid)
  	sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
  	max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
  
- 	/* Make sure nextXid is beyond any XID mentioned in the record */
- 
  	/*
  	 * We don't expect anyone else to modify nextXid, hence we don't need to
  	 * hold a lock while checking this. We still acquire the lock to modify
  	 * it, though.
--- 4522,4530 ----
  	sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]);
  	max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids);
  
  	/*
+ 	 * Make sure nextXid is beyond any XID mentioned in the record.
+ 	 *
  	 * We don't expect anyone else to modify nextXid, hence we don't need to
  	 * hold a lock while checking this. We still acquire the lock to modify
  	 * it, though.
*** a/src/backend/storage/ipc/procarray.c
--- b/src/backend/storage/ipc/procarray.c
***************
*** 449,455 **** ProcArrayInitRecoveryInfo(TransactionId oldestActiveXid)
  /*
   * ProcArrayApplyRecoveryInfo -- apply recovery info about xids
   *
!  * Takes us through 3 states: Uninitialized, Pending and Ready.
   * Normal case is to go all the way to Ready straight away, though there
   * are atypical cases where we need to take it in steps.
   *
--- 449,455 ----
  /*
   * ProcArrayApplyRecoveryInfo -- apply recovery info about xids
   *
!  * Takes us through 3 states: Initialized, Pending and Ready.
   * Normal case is to go all the way to Ready straight away, though there
   * are atypical cases where we need to take it in steps.
   *
***************
*** 487,493 **** ProcArrayApplyRecoveryInfo(RunningTransactions running)
  		return;
  
  	/*
! 	 * If our initial RunningXactData had an overflowed snapshot then we knew
  	 * we were missing some subxids from our snapshot. We can use this data as
  	 * an initial snapshot, but we cannot yet mark it valid. We know that the
  	 * missing subxids are equal to or earlier than nextXid. After we
--- 487,493 ----
  		return;
  
  	/*
! 	 * If our initial RunningTransactionsData had an overflowed snapshot then we knew
  	 * we were missing some subxids from our snapshot. We can use this data as
  	 * an initial snapshot, but we cannot yet mark it valid. We know that the
  	 * missing subxids are equal to or earlier than nextXid. After we
***************
*** 518,524 **** ProcArrayApplyRecoveryInfo(RunningTransactions running)
  	Assert(standbyState == STANDBY_INITIALIZED);
  
  	/*
! 	 * OK, we need to initialise from the RunningXactData record
  	 */
  
  	/*
--- 518,524 ----
  	Assert(standbyState == STANDBY_INITIALIZED);
  
  	/*
! 	 * OK, we need to initialise from the RunningTransactionsData record
  	 */
  
  	/*
***************
*** 1499,1505 **** GetRunningTransactionData(void)
  				suboverflowed = true;
  
  			/*
! 			 * Top-level XID of a transaction is always greater than any of
  			 * its subxids, so we don't need to check if any of the subxids
  			 * are smaller than oldestRunningXid
  			 */
--- 1499,1505 ----
  				suboverflowed = true;
  
  			/*
! 			 * Top-level XID of a transaction is always less than any of
  			 * its subxids, so we don't need to check if any of the subxids
  			 * are smaller than oldestRunningXid
  			 */
***************
*** 2313,2319 **** DisplayXidCache(void)
   * aborted but we think they were running; the distinction is irrelevant
   * because either way any changes done by the transaction are not visible to
   * backends in the standby.  We prune KnownAssignedXids when
!  * XLOG_XACT_RUNNING_XACTS arrives, to forestall possible overflow of the
   * array due to such dead XIDs.
   */
  
--- 2313,2319 ----
   * aborted but we think they were running; the distinction is irrelevant
   * because either way any changes done by the transaction are not visible to
   * backends in the standby.  We prune KnownAssignedXids when
!  * XLOG_RUNNING_XACTS arrives, to forestall possible overflow of the
   * array due to such dead XIDs.
   */
  
***************
*** 2323,2331 **** DisplayXidCache(void)
   *		unobserved XIDs.
   *
   * RecordKnownAssignedTransactionIds() should be run for *every* WAL record
!  * type apart from XLOG_XACT_RUNNING_XACTS (since that initialises the first
   * snapshot so that RecordKnownAssignedTransactionIds() can be called). Must
!  * be called for each record after we have executed StartupCLog() et al,
   * since we must ExtendCLOG() etc..
   *
   * Called during recovery in analogy with and in place of GetNewTransactionId()
--- 2323,2331 ----
   *		unobserved XIDs.
   *
   * RecordKnownAssignedTransactionIds() should be run for *every* WAL record
!  * type apart from XLOG_RUNNING_XACTS (since that initialises the first
   * snapshot so that RecordKnownAssignedTransactionIds() can be called). Must
!  * be called for each record after we have executed StartupCLOG() et al,
   * since we must ExtendCLOG() etc..
   *
   * Called during recovery in analogy with and in place of GetNewTransactionId()
***************
*** 3046,3056 **** KnownAssignedXidsDisplay(int trace_level)
  		if (KnownAssignedXidsValid[i])
  		{
  			nxids++;
! 			appendStringInfo(&buf, "[%u]=%u ", i, KnownAssignedXids[i]);
  		}
  	}
  
! 	elog(trace_level, "%d KnownAssignedXids (num=%u tail=%u head=%u) %s",
  		 nxids,
  		 pArray->numKnownAssignedXids,
  		 pArray->tailKnownAssignedXids,
--- 3046,3056 ----
  		if (KnownAssignedXidsValid[i])
  		{
  			nxids++;
! 			appendStringInfo(&buf, "[%d]=%u ", i, KnownAssignedXids[i]);
  		}
  	}
  
! 	elog(trace_level, "%d KnownAssignedXids (num=%d tail=%d head=%d) %s",
  		 nxids,
  		 pArray->numKnownAssignedXids,
  		 pArray->tailKnownAssignedXids,
*** a/src/backend/storage/ipc/standby.c
--- b/src/backend/storage/ipc/standby.c
***************
*** 522,528 **** CheckRecoveryConflictDeadlock(LWLockId partitionLock)
   * one transaction on one relation, and don't worry about lock queuing.
   *
   * We keep a single dynamically expandible list of locks in local memory,
!  * RelationLockList, so we can keep track of the various entried made by
   * the Startup process's virtual xid in the shared lock table.
   *
   * List elements use type xl_rel_lock, since the WAL record type exactly
--- 522,528 ----
   * one transaction on one relation, and don't worry about lock queuing.
   *
   * We keep a single dynamically expandible list of locks in local memory,
!  * RelationLockList, so we can keep track of the various entries made by
   * the Startup process's virtual xid in the shared lock table.
   *
   * List elements use type xl_rel_lock, since the WAL record type exactly
***************
*** 700,706 **** standby_redo(XLogRecPtr lsn, XLogRecord *record)
  {
  	uint8		info = record->xl_info & ~XLR_INFO_MASK;
  
! 	/* Do nothing if we're not in standby mode */
  	if (standbyState == STANDBY_DISABLED)
  		return;
  
--- 700,706 ----
  {
  	uint8		info = record->xl_info & ~XLR_INFO_MASK;
  
! 	/* Do nothing if we're not in hot standby mode */
  	if (standbyState == STANDBY_DISABLED)
  		return;
  
***************
*** 872,878 **** LogStandbySnapshot(TransactionId *oldestActiveXid, TransactionId *nextXid)
  /*
   * Record an enhanced snapshot of running transactions into WAL.
   *
!  * The definitions of RunningTransactionData and xl_xact_running_xacts
   * are similar. We keep them separate because xl_xact_running_xacts
   * is a contiguous chunk of memory and never exists fully until it is
   * assembled in WAL.
--- 872,878 ----
  /*
   * Record an enhanced snapshot of running transactions into WAL.
   *
!  * The definitions of RunningTransactionsData and xl_xact_running_xacts
   * are similar. We keep them separate because xl_xact_running_xacts
   * is a contiguous chunk of memory and never exists fully until it is
   * assembled in WAL.
*** a/src/backend/tcop/postgres.c
--- b/src/backend/tcop/postgres.c
***************
*** 2741,2747 **** SigHupHandler(SIGNAL_ARGS)
  
  /*
   * RecoveryConflictInterrupt: out-of-line portion of recovery conflict
!  * handling ollowing receipt of SIGUSR1. Designed to be similar to die()
   * and StatementCancelHandler(). Called only by a normal user backend
   * that begins a transaction during recovery.
   */
--- 2741,2747 ----
  
  /*
   * RecoveryConflictInterrupt: out-of-line portion of recovery conflict
!  * handling following receipt of SIGUSR1. Designed to be similar to die()
   * and StatementCancelHandler(). Called only by a normal user backend
   * that begins a transaction during recovery.
   */
*** a/src/include/access/xlog.h
--- b/src/include/access/xlog.h
***************
*** 149,155 **** extern bool InRecovery;
   * InHotStandby will read as FALSE).
   *
   * In DISABLED state, we're performing crash recovery or hot standby was
!  * disabled in recovery.conf.
   *
   * In INITIALIZED state, we've run InitRecoveryTransactionEnvironment, but
   * we haven't yet processed a RUNNING_XACTS or shutdown-checkpoint WAL record
--- 149,155 ----
   * InHotStandby will read as FALSE).
   *
   * In DISABLED state, we're performing crash recovery or hot standby was
!  * disabled in postgresql.conf.
   *
   * In INITIALIZED state, we've run InitRecoveryTransactionEnvironment, but
   * we haven't yet processed a RUNNING_XACTS or shutdown-checkpoint WAL record
*** a/src/include/catalog/pg_control.h
--- b/src/include/catalog/pg_control.h
***************
*** 45,51 **** typedef struct CheckPoint
  	/*
  	 * Oldest XID still running. This is only needed to initialize hot standby
  	 * mode from an online checkpoint, so we only bother calculating this for
! 	 * online checkpoints and only when archiving is enabled. Otherwise it's
  	 * set to InvalidTransactionId.
  	 */
  	TransactionId oldestActiveXid;
--- 45,51 ----
  	/*
  	 * Oldest XID still running. This is only needed to initialize hot standby
  	 * mode from an online checkpoint, so we only bother calculating this for
! 	 * online checkpoints and only when wal_level is hot_standby. Otherwise it's
  	 * set to InvalidTransactionId.
  	 */
  	TransactionId oldestActiveXid;
