diff options
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 67 |
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; } |