Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaf4aba2

Browse files
committed
Ensure recovery pause feature doesn't pause unless users can connect.
If we're not in hot standby mode, then there's no way for users to connectto reset the recoveryPause flag, so we shouldn't pause. The code was awareof this but the test to see if pausing was safe was seriously inadequate:it wasn't paying attention to reachedConsistency, and besides what it wastesting was that we could legally enter hot standby, not that we havedone so. Get rid of that in favor of checking LocalHotStandbyActive,which because of the coding in CheckRecoveryConsistency is tantamount tochecking that we have told the postmaster to enter hot standby.Also, move the recoveryPausesHere() call that reacts to asynchronousrecoveryPause requests so that it's not in the middle of application of aWAL record. I put it next to the recoveryStopsHere() call --- in futurethose are going to need to interact significantly, so this seems like agood waystation.Also, don't bother trying to read another WAL record if we've alreadydecided not to continue recovery. This was no big deal when the code waswritten originally, but now that reading a record might entail actions likefetching an archive file, it seems a bit silly to do it like that.Per report from Jeff Janes and subsequent discussion. The pause featureneeds quite a lot more work, but this gets rid of some indisputable bugs,and seems safe enough to back-patch.
1 parentd67b06f commitaf4aba2

File tree

1 file changed

+34
-16
lines changed
  • src/backend/access/transam

1 file changed

+34
-16
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5039,13 +5039,19 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
50395039
}
50405040

50415041
/*
5042-
*Recheckshared recoveryPauseby polling.
5042+
*Wait untilshared recoveryPauseflag is cleared.
50435043
*
5044-
* XXX Can also be done with shared latch.
5044+
* XXX Could also be done with shared latch, avoiding the pg_usleep loop.
5045+
* Probably not worth the trouble though. This state shouldn't be one that
5046+
* anyone cares about server power consumption in.
50455047
*/
50465048
staticvoid
50475049
recoveryPausesHere(void)
50485050
{
5051+
/* Don't pause unless users can connect! */
5052+
if (!LocalHotStandbyActive)
5053+
return;
5054+
50495055
ereport(LOG,
50505056
(errmsg("recovery has paused"),
50515057
errhint("Execute pg_xlog_replay_resume() to continue.")));
@@ -5806,7 +5812,6 @@ StartupXLOG(void)
58065812
{
58075813
boolrecoveryContinue= true;
58085814
boolrecoveryApply= true;
5809-
boolrecoveryPause= false;
58105815
ErrorContextCallbackerrcallback;
58115816
TimestampTzxtime;
58125817

@@ -5848,22 +5853,36 @@ StartupXLOG(void)
58485853
/* Allow read-only connections if we're consistent now */
58495854
CheckRecoveryConsistency();
58505855

5856+
/*
5857+
* Pause WAL replay, if requested by a hot-standby session via
5858+
* SetRecoveryPause().
5859+
*
5860+
* Note that we intentionally don't take the info_lck spinlock
5861+
* here. We might therefore read a slightly stale value of
5862+
* the recoveryPause flag, but it can't be very stale (no
5863+
* worse than the last spinlock we did acquire). Since a
5864+
* pause request is a pretty asynchronous thing anyway,
5865+
* possibly responding to it one WAL record later than we
5866+
* otherwise would is a minor issue, so it doesn't seem worth
5867+
* adding another spinlock cycle to prevent that.
5868+
*/
5869+
if (xlogctl->recoveryPause)
5870+
recoveryPausesHere();
5871+
58515872
/*
58525873
* Have we reached our recovery target?
58535874
*/
58545875
if (recoveryStopsHere(record,&recoveryApply))
58555876
{
5856-
/*
5857-
* Pause only if users can connect to send a resume
5858-
* message
5859-
*/
5860-
if (recoveryPauseAtTarget&&standbyState==STANDBY_SNAPSHOT_READY)
5877+
if (recoveryPauseAtTarget)
58615878
{
58625879
SetRecoveryPause(true);
58635880
recoveryPausesHere();
58645881
}
58655882
reachedStopPoint= true;/* see below */
58665883
recoveryContinue= false;
5884+
5885+
/* Exit loop if we reached non-inclusive recovery target */
58675886
if (!recoveryApply)
58685887
break;
58695888
}
@@ -5896,15 +5915,8 @@ StartupXLOG(void)
58965915
*/
58975916
SpinLockAcquire(&xlogctl->info_lck);
58985917
xlogctl->replayEndRecPtr=EndRecPtr;
5899-
recoveryPause=xlogctl->recoveryPause;
59005918
SpinLockRelease(&xlogctl->info_lck);
59015919

5902-
/*
5903-
* Pause only if users can connect to send a resume message
5904-
*/
5905-
if (recoveryPause&&standbyState==STANDBY_SNAPSHOT_READY)
5906-
recoveryPausesHere();
5907-
59085920
/*
59095921
* If we are attempting to enter Hot Standby mode, process
59105922
* XIDs we see
@@ -5948,10 +5960,16 @@ StartupXLOG(void)
59485960
xlogctl->recoveryLastRecPtr=EndRecPtr;
59495961
SpinLockRelease(&xlogctl->info_lck);
59505962

5963+
/* Remember this record as the last-applied one */
59515964
LastRec=ReadRecPtr;
59525965

5966+
/* Exit loop if we reached inclusive recovery target */
5967+
if (!recoveryContinue)
5968+
break;
5969+
5970+
/* Else, try to fetch the next WAL record */
59535971
record=ReadRecord(NULL,LOG, false);
5954-
}while (record!=NULL&&recoveryContinue);
5972+
}while (record!=NULL);
59555973

59565974
/*
59575975
* end of main redo apply loop

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp