@ -158,6 +158,11 @@ static XLogRecPtr LastRec;
* known , need to check the shared state " .
*/
static bool LocalRecoveryInProgress = true ;
/*
* Local copy of SharedHotStandbyActive variable . False actually means " not
* known , need to check the shared state " .
*/
static bool LocalHotStandbyActive = false ;
/*
* Local state for XLogInsertAllowed ( ) :
@ -405,6 +410,12 @@ typedef struct XLogCtlData
*/
bool SharedRecoveryInProgress ;
/*
* SharedHotStandbyActive indicates if we ' re still in crash or archive
* recovery . Protected by info_lck .
*/
bool SharedHotStandbyActive ;
/*
* recoveryWakeupLatch is used to wake up the startup process to
* continue WAL replay , if it is waiting for WAL to arrive or failover
@ -4917,6 +4928,7 @@ XLOGShmemInit(void)
*/
XLogCtl - > XLogCacheBlck = XLOGbuffers - 1 ;
XLogCtl - > SharedRecoveryInProgress = true ;
XLogCtl - > SharedHotStandbyActive = false ;
XLogCtl - > Insert . currpage = ( XLogPageHeader ) ( XLogCtl - > pages ) ;
SpinLockInit ( & XLogCtl - > info_lck ) ;
InitSharedLatch ( & XLogCtl - > recoveryWakeupLatch ) ;
@ -6790,8 +6802,6 @@ StartupXLOG(void)
static void
CheckRecoveryConsistency ( void )
{
static bool backendsAllowed = false ;
/*
* Have we passed our safe starting point ?
*/
@ -6811,11 +6821,19 @@ CheckRecoveryConsistency(void)
* enabling connections .
*/
if ( standbyState = = STANDBY_SNAPSHOT_READY & &
! backendsAllowed & &
! LocalHotStandbyActive & &
reachedMinRecoveryPoint & &
IsUnderPostmaster )
{
backendsAllowed = true ;
/* use volatile pointer to prevent code rearrangement */
volatile XLogCtlData * xlogctl = XLogCtl ;
SpinLockAcquire ( & xlogctl - > info_lck ) ;
xlogctl - > SharedHotStandbyActive = true ;
SpinLockRelease ( & xlogctl - > info_lck ) ;
LocalHotStandbyActive = true ;
SendPostmasterSignal ( PMSIGNAL_BEGIN_HOT_STANDBY ) ;
}
}
@ -6862,6 +6880,38 @@ RecoveryInProgress(void)
}
}
/*
* 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 .
*
* Unlike testing standbyState , this works in any process that ' s connected to
* shared memory .
*/
bool
HotStandbyActive ( void )
{
/*
* We check shared state each time only until Hot Standby is active . We
* can ' t de - activate Hot Standby , so there ' s no need to keep checking after
* the shared variable has once been seen true .
*/
if ( LocalHotStandbyActive )
return true ;
else
{
/* use volatile pointer to prevent code rearrangement */
volatile XLogCtlData * xlogctl = XLogCtl ;
/* spinlock is essential on machines with weak memory ordering! */
SpinLockAcquire ( & xlogctl - > info_lck ) ;
LocalHotStandbyActive = xlogctl - > SharedHotStandbyActive ;
SpinLockRelease ( & xlogctl - > info_lck ) ;
return LocalHotStandbyActive ;
}
}
/*
* Is this process allowed to insert new WAL records ?
*