aboutsummaryrefslogtreecommitdiff
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.c67
1 files changed, 60 insertions, 7 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 64860f12f56..7621fc05e24 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -230,6 +230,12 @@ static bool LocalRecoveryInProgress = true;
static bool LocalHotStandbyActive = false;
/*
+ * Local copy of SharedPromoteIsTriggered variable. False actually means "not
+ * known, need to check the shared state".
+ */
+static bool LocalPromoteIsTriggered = false;
+
+/*
* Local state for XLogInsertAllowed():
* 1: unconditionally allowed to insert XLOG
* 0: unconditionally not allowed to insert XLOG
@@ -655,6 +661,12 @@ typedef struct XLogCtlData
bool SharedHotStandbyActive;
/*
+ * SharedPromoteIsTriggered indicates if a standby promotion has been
+ * triggered. Protected by info_lck.
+ */
+ bool SharedPromoteIsTriggered;
+
+ /*
* WalWriterSleeping indicates whether the WAL writer is currently in
* low-power mode (and hence should be nudged if an async commit occurs).
* Protected by info_lck.
@@ -912,6 +924,7 @@ static void InitControlFile(uint64 sysidentifier);
static void WriteControlFile(void);
static void ReadControlFile(void);
static char *str_time(pg_time_t tnow);
+static void SetPromoteIsTriggered(void);
static bool CheckForStandbyTrigger(void);
#ifdef WAL_DEBUG
@@ -5112,6 +5125,7 @@ XLOGShmemInit(void)
XLogCtl->XLogCacheBlck = XLOGbuffers - 1;
XLogCtl->SharedRecoveryInProgress = true;
XLogCtl->SharedHotStandbyActive = false;
+ XLogCtl->SharedPromoteIsTriggered = false;
XLogCtl->WalWriterSleeping = false;
SpinLockInit(&XLogCtl->Insert.insertpos_lck);
@@ -5940,16 +5954,22 @@ recoveryPausesHere(void)
if (!LocalHotStandbyActive)
return;
+ /* Don't pause after standby promotion has been triggered */
+ if (LocalPromoteIsTriggered)
+ return;
+
ereport(LOG,
(errmsg("recovery has paused"),
errhint("Execute pg_wal_replay_resume() to continue.")));
while (RecoveryIsPaused())
{
+ HandleStartupProcInterrupts();
+ if (CheckForStandbyTrigger())
+ return;
pgstat_report_wait_start(WAIT_EVENT_RECOVERY_PAUSE);
pg_usleep(1000000L); /* 1000 ms */
pgstat_report_wait_end();
- HandleStartupProcInterrupts();
}
}
@@ -12278,6 +12298,40 @@ emode_for_corrupt_record(int emode, XLogRecPtr RecPtr)
}
/*
+ * Has a standby promotion already been triggered?
+ *
+ * Unlike CheckForStandbyTrigger(), this works in any process
+ * that's connected to shared memory.
+ */
+bool
+PromoteIsTriggered(void)
+{
+ /*
+ * We check shared state each time only until a standby promotion is
+ * triggered. We can't trigger a promotion again, so there's no need to
+ * keep checking after the shared variable has once been seen true.
+ */
+ if (LocalPromoteIsTriggered)
+ return true;
+
+ SpinLockAcquire(&XLogCtl->info_lck);
+ LocalPromoteIsTriggered = XLogCtl->SharedPromoteIsTriggered;
+ SpinLockRelease(&XLogCtl->info_lck);
+
+ return LocalPromoteIsTriggered;
+}
+
+static void
+SetPromoteIsTriggered(void)
+{
+ SpinLockAcquire(&XLogCtl->info_lck);
+ XLogCtl->SharedPromoteIsTriggered = true;
+ SpinLockRelease(&XLogCtl->info_lck);
+
+ LocalPromoteIsTriggered = true;
+}
+
+/*
* Check to see whether the user-specified trigger file exists and whether a
* promote request has arrived. If either condition holds, return true.
*/
@@ -12285,12 +12339,11 @@ static bool
CheckForStandbyTrigger(void)
{
struct stat stat_buf;
- static bool triggered = false;
- if (triggered)
+ if (LocalPromoteIsTriggered)
return true;
- if (IsPromoteTriggered())
+ if (IsPromoteSignaled())
{
/*
* In 9.1 and 9.2 the postmaster unlinked the promote file inside the
@@ -12313,8 +12366,8 @@ CheckForStandbyTrigger(void)
ereport(LOG, (errmsg("received promote request")));
- ResetPromoteTriggered();
- triggered = true;
+ ResetPromoteSignaled();
+ SetPromoteIsTriggered();
return true;
}
@@ -12326,7 +12379,7 @@ CheckForStandbyTrigger(void)
ereport(LOG,
(errmsg("promote trigger file found: %s", PromoteTriggerFile)));
unlink(PromoteTriggerFile);
- triggered = true;
+ SetPromoteIsTriggered();
fast_promote = true;
return true;
}