@@ -816,9 +816,13 @@ static XLogSource readSource = XLOG_FROM_ANY;
816
816
* currently have a WAL file open. If lastSourceFailed is set, our last
817
817
* attempt to read from currentSource failed, and we should try another source
818
818
* next.
819
+ *
820
+ * pendingWalRcvRestart is set when a config change occurs that requires a
821
+ * walreceiver restart. This is only valid in XLOG_FROM_STREAM state.
819
822
*/
820
823
static XLogSource currentSource = XLOG_FROM_ANY ;
821
824
static bool lastSourceFailed = false;
825
+ static bool pendingWalRcvRestart = false;
822
826
823
827
typedef struct XLogPageReadPrivate
824
828
{
@@ -11905,6 +11909,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
11905
11909
for (;;)
11906
11910
{
11907
11911
XLogSource oldSource = currentSource ;
11912
+ bool startWalReceiver = false;
11908
11913
11909
11914
/*
11910
11915
* First check if we failed to read from the current source, and
@@ -11939,54 +11944,11 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
11939
11944
return false;
11940
11945
11941
11946
/*
11942
- * If primary_conninfo is set, launch walreceiver to try
11943
- * to stream the missing WAL.
11944
- *
11945
- * If fetching_ckpt is true, RecPtr points to the initial
11946
- * checkpoint location. In that case, we use RedoStartLSN
11947
- * as the streaming start position instead of RecPtr, so
11948
- * that when we later jump backwards to start redo at
11949
- * RedoStartLSN, we will have the logs streamed already.
11950
- */
11951
- if (PrimaryConnInfo && strcmp (PrimaryConnInfo ,"" )!= 0 )
11952
- {
11953
- XLogRecPtr ptr ;
11954
- TimeLineID tli ;
11955
-
11956
- if (fetching_ckpt )
11957
- {
11958
- ptr = RedoStartLSN ;
11959
- tli = ControlFile -> checkPointCopy .ThisTimeLineID ;
11960
- }
11961
- else
11962
- {
11963
- ptr = RecPtr ;
11964
-
11965
- /*
11966
- * Use the record begin position to determine the
11967
- * TLI, rather than the position we're reading.
11968
- */
11969
- tli = tliOfPointInHistory (tliRecPtr ,expectedTLEs );
11970
-
11971
- if (curFileTLI > 0 && tli < curFileTLI )
11972
- elog (ERROR ,"according to history file, WAL location %X/%X belongs to timeline %u, but previous recovered WAL file came from timeline %u" ,
11973
- (uint32 ) (tliRecPtr >>32 ),
11974
- (uint32 )tliRecPtr ,
11975
- tli ,curFileTLI );
11976
- }
11977
- curFileTLI = tli ;
11978
- RequestXLogStreaming (tli ,ptr ,PrimaryConnInfo ,
11979
- PrimarySlotName ,
11980
- wal_receiver_create_temp_slot );
11981
- receivedUpto = 0 ;
11982
- }
11983
-
11984
- /*
11985
- * Move to XLOG_FROM_STREAM state in either case. We'll
11986
- * get immediate failure if we didn't launch walreceiver,
11987
- * and move on to the next state.
11947
+ * Move to XLOG_FROM_STREAM state, and set to start a
11948
+ * walreceiver if necessary.
11988
11949
*/
11989
11950
currentSource = XLOG_FROM_STREAM ;
11951
+ startWalReceiver = true;
11990
11952
break ;
11991
11953
11992
11954
case XLOG_FROM_STREAM :
@@ -12138,7 +12100,71 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
12138
12100
Assert (StandbyMode );
12139
12101
12140
12102
/*
12141
- * Check if WAL receiver is still active.
12103
+ * First, shutdown walreceiver if its restart has been
12104
+ * requested -- but no point if we're already slated for
12105
+ * starting it.
12106
+ */
12107
+ if (pendingWalRcvRestart && !startWalReceiver )
12108
+ {
12109
+ ShutdownWalRcv ();
12110
+
12111
+ /*
12112
+ * Re-scan for possible new timelines if we were
12113
+ * requested to recover to the latest timeline.
12114
+ */
12115
+ if (recoveryTargetTimeLineGoal ==
12116
+ RECOVERY_TARGET_TIMELINE_LATEST )
12117
+ rescanLatestTimeLine ();
12118
+
12119
+ startWalReceiver = true;
12120
+ }
12121
+ pendingWalRcvRestart = false;
12122
+
12123
+ /*
12124
+ * Launch walreceiver if needed.
12125
+ *
12126
+ * If fetching_ckpt is true, RecPtr points to the initial
12127
+ * checkpoint location. In that case, we use RedoStartLSN
12128
+ * as the streaming start position instead of RecPtr, so
12129
+ * that when we later jump backwards to start redo at
12130
+ * RedoStartLSN, we will have the logs streamed already.
12131
+ */
12132
+ if (startWalReceiver &&
12133
+ PrimaryConnInfo && strcmp (PrimaryConnInfo ,"" )!= 0 )
12134
+ {
12135
+ XLogRecPtr ptr ;
12136
+ TimeLineID tli ;
12137
+
12138
+ if (fetching_ckpt )
12139
+ {
12140
+ ptr = RedoStartLSN ;
12141
+ tli = ControlFile -> checkPointCopy .ThisTimeLineID ;
12142
+ }
12143
+ else
12144
+ {
12145
+ ptr = RecPtr ;
12146
+
12147
+ /*
12148
+ * Use the record begin position to determine the
12149
+ * TLI, rather than the position we're reading.
12150
+ */
12151
+ tli = tliOfPointInHistory (tliRecPtr ,expectedTLEs );
12152
+
12153
+ if (curFileTLI > 0 && tli < curFileTLI )
12154
+ elog (ERROR ,"according to history file, WAL location %X/%X belongs to timeline %u, but previous recovered WAL file came from timeline %u" ,
12155
+ (uint32 ) (tliRecPtr >>32 ),
12156
+ (uint32 )tliRecPtr ,
12157
+ tli ,curFileTLI );
12158
+ }
12159
+ curFileTLI = tli ;
12160
+ RequestXLogStreaming (tli ,ptr ,PrimaryConnInfo ,
12161
+ PrimarySlotName ,
12162
+ wal_receiver_create_temp_slot );
12163
+ receivedUpto = 0 ;
12164
+ }
12165
+
12166
+ /*
12167
+ * Check if WAL receiver is active or wait to start up.
12142
12168
*/
12143
12169
if (!WalRcvStreaming ())
12144
12170
{
@@ -12266,6 +12292,22 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
12266
12292
return false;/* not reached */
12267
12293
}
12268
12294
12295
+ /*
12296
+ * Set flag to signal the walreceiver to restart. (The startup process calls
12297
+ * this on noticing a relevant configuration change.)
12298
+ */
12299
+ void
12300
+ StartupRequestWalReceiverRestart (void )
12301
+ {
12302
+ if (currentSource == XLOG_FROM_STREAM && WalRcvRunning ())
12303
+ {
12304
+ ereport (LOG ,
12305
+ (errmsg ("wal receiver process shutdown requested" )));
12306
+
12307
+ pendingWalRcvRestart = true;
12308
+ }
12309
+ }
12310
+
12269
12311
/*
12270
12312
* Determine what log level should be used to report a corrupt WAL record
12271
12313
* in the current WAL page, previously read by XLogPageRead().