summaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c57
1 files changed, 48 insertions, 9 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 823efdbed0d..acca98ea288 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -204,8 +204,9 @@ static TimeLineID receiveTLI = 0;
static bool lastFullPageWrites;
/*
- * Local copy of SharedRecoveryInProgress variable. True actually means "not
- * known, need to check the shared state".
+ * Local copy of the state tracked by SharedRecoveryState in shared memory,
+ * It is false if SharedRecoveryState is RECOVERY_STATE_DONE. True actually
+ * means "not known, need to check the shared state".
*/
static bool LocalRecoveryInProgress = true;
@@ -616,10 +617,10 @@ typedef struct XLogCtlData
char archiveCleanupCommand[MAXPGPATH];
/*
- * SharedRecoveryInProgress indicates if we're still in crash or archive
+ * SharedRecoveryState indicates if we're still in crash or archive
* recovery. Protected by info_lck.
*/
- bool SharedRecoveryInProgress;
+ RecoveryState SharedRecoveryState;
/*
* SharedHotStandbyActive indicates if we're still in crash or archive
@@ -4136,6 +4137,16 @@ ReadRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode,
updateMinRecoveryPoint = true;
UpdateControlFile();
+
+ /*
+ * We update SharedRecoveryState while holding the lock on
+ * ControlFileLock so both states are consistent in shared
+ * memory.
+ */
+ SpinLockAcquire(&XLogCtl->info_lck);
+ XLogCtl->SharedRecoveryState = RECOVERY_STATE_ARCHIVE;
+ SpinLockRelease(&XLogCtl->info_lck);
+
LWLockRelease(ControlFileLock);
CheckRecoveryConsistency();
@@ -4819,7 +4830,7 @@ XLOGShmemInit(void)
* in additional info.)
*/
XLogCtl->XLogCacheBlck = XLOGbuffers - 1;
- XLogCtl->SharedRecoveryInProgress = true;
+ XLogCtl->SharedRecoveryState = RECOVERY_STATE_CRASH;
XLogCtl->SharedHotStandbyActive = false;
XLogCtl->WalWriterSleeping = false;
@@ -6541,7 +6552,13 @@ StartupXLOG(void)
*/
dbstate_at_startup = ControlFile->state;
if (InArchiveRecovery)
+ {
ControlFile->state = DB_IN_ARCHIVE_RECOVERY;
+
+ SpinLockAcquire(&XLogCtl->info_lck);
+ XLogCtl->SharedRecoveryState = RECOVERY_STATE_ARCHIVE;
+ SpinLockRelease(&XLogCtl->info_lck);
+ }
else
{
ereport(LOG,
@@ -6554,6 +6571,10 @@ StartupXLOG(void)
ControlFile->checkPointCopy.ThisTimeLineID,
recoveryTargetTLI)));
ControlFile->state = DB_IN_CRASH_RECOVERY;
+
+ SpinLockAcquire(&XLogCtl->info_lck);
+ XLogCtl->SharedRecoveryState = RECOVERY_STATE_CRASH;
+ SpinLockRelease(&XLogCtl->info_lck);
}
ControlFile->prevCheckPoint = ControlFile->checkPoint;
ControlFile->checkPoint = checkPointLoc;
@@ -7555,7 +7576,7 @@ StartupXLOG(void)
* updates to shared memory.)
*/
SpinLockAcquire(&XLogCtl->info_lck);
- XLogCtl->SharedRecoveryInProgress = false;
+ XLogCtl->SharedRecoveryState = RECOVERY_STATE_DONE;
SpinLockRelease(&XLogCtl->info_lck);
/*
@@ -7698,7 +7719,7 @@ RecoveryInProgress(void)
*/
volatile XLogCtlData *xlogctl = XLogCtl;
- LocalRecoveryInProgress = xlogctl->SharedRecoveryInProgress;
+ LocalRecoveryInProgress = (xlogctl->SharedRecoveryState != RECOVERY_STATE_DONE);
/*
* Initialize TimeLineID and RedoRecPtr when we discover that recovery
@@ -7710,8 +7731,8 @@ RecoveryInProgress(void)
{
/*
* If we just exited recovery, make sure we read TimeLineID and
- * RedoRecPtr after SharedRecoveryInProgress (for machines with
- * weak memory ordering).
+ * RedoRecPtr after SharedRecoveryState (for machines with weak
+ * memory ordering).
*/
pg_memory_barrier();
InitXLOGAccess();
@@ -7728,6 +7749,24 @@ RecoveryInProgress(void)
}
/*
+ * Returns current recovery state from shared memory.
+ *
+ * This returned state is kept consistent with the contents of the control
+ * file. See details about the possible values of RecoveryState in xlog.h.
+ */
+RecoveryState
+GetRecoveryState(void)
+{
+ RecoveryState retval;
+
+ SpinLockAcquire(&XLogCtl->info_lck);
+ retval = XLogCtl->SharedRecoveryState;
+ SpinLockRelease(&XLogCtl->info_lck);
+
+ return retval;
+}
+
+/*
* 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.