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 ec66b99b325..c10dc889c61 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -209,8 +209,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;
@@ -635,10 +636,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
@@ -4295,6 +4296,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();
@@ -4980,7 +4991,7 @@ XLOGShmemInit(void)
* in additional info.)
*/
XLogCtl->XLogCacheBlck = XLOGbuffers - 1;
- XLogCtl->SharedRecoveryInProgress = true;
+ XLogCtl->SharedRecoveryState = RECOVERY_STATE_CRASH;
XLogCtl->SharedHotStandbyActive = false;
XLogCtl->WalWriterSleeping = false;
@@ -6803,7 +6814,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,
@@ -6816,6 +6833,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;
@@ -7841,7 +7862,7 @@ StartupXLOG(void)
ControlFile->time = (pg_time_t) time(NULL);
SpinLockAcquire(&XLogCtl->info_lck);
- XLogCtl->SharedRecoveryInProgress = false;
+ XLogCtl->SharedRecoveryState = RECOVERY_STATE_DONE;
SpinLockRelease(&XLogCtl->info_lck);
UpdateControlFile();
@@ -7987,7 +8008,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
@@ -7999,8 +8020,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();
@@ -8017,6 +8038,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.