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

Commit9d1a293

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 parent93c041a commit9d1a293

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
@@ -5788,13 +5788,19 @@ recoveryStopsHere(XLogRecord *record, bool *includeThis)
57885788
}
57895789

57905790
/*
5791-
*Recheckshared recoveryPauseby polling.
5791+
*Wait untilshared recoveryPauseflag is cleared.
57925792
*
5793-
* XXX Can also be done with shared latch.
5793+
* XXX Could also be done with shared latch, avoiding the pg_usleep loop.
5794+
* Probably not worth the trouble though. This state shouldn't be one that
5795+
* anyone cares about server power consumption in.
57945796
*/
57955797
staticvoid
57965798
recoveryPausesHere(void)
57975799
{
5800+
/* Don't pause unless users can connect! */
5801+
if (!LocalHotStandbyActive)
5802+
return;
5803+
57985804
ereport(LOG,
57995805
(errmsg("recovery has paused"),
58005806
errhint("Execute pg_xlog_replay_resume() to continue.")));
@@ -6552,7 +6558,6 @@ StartupXLOG(void)
65526558
{
65536559
boolrecoveryContinue= true;
65546560
boolrecoveryApply= true;
6555-
boolrecoveryPause= false;
65566561
ErrorContextCallbackerrcontext;
65576562
TimestampTzxtime;
65586563

@@ -6594,22 +6599,36 @@ StartupXLOG(void)
65946599
/* Allow read-only connections if we're consistent now */
65956600
CheckRecoveryConsistency();
65966601

6602+
/*
6603+
* Pause WAL replay, if requested by a hot-standby session via
6604+
* SetRecoveryPause().
6605+
*
6606+
* Note that we intentionally don't take the info_lck spinlock
6607+
* here. We might therefore read a slightly stale value of
6608+
* the recoveryPause flag, but it can't be very stale (no
6609+
* worse than the last spinlock we did acquire). Since a
6610+
* pause request is a pretty asynchronous thing anyway,
6611+
* possibly responding to it one WAL record later than we
6612+
* otherwise would is a minor issue, so it doesn't seem worth
6613+
* adding another spinlock cycle to prevent that.
6614+
*/
6615+
if (xlogctl->recoveryPause)
6616+
recoveryPausesHere();
6617+
65976618
/*
65986619
* Have we reached our recovery target?
65996620
*/
66006621
if (recoveryStopsHere(record,&recoveryApply))
66016622
{
6602-
/*
6603-
* Pause only if users can connect to send a resume
6604-
* message
6605-
*/
6606-
if (recoveryPauseAtTarget&&standbyState==STANDBY_SNAPSHOT_READY)
6623+
if (recoveryPauseAtTarget)
66076624
{
66086625
SetRecoveryPause(true);
66096626
recoveryPausesHere();
66106627
}
66116628
reachedStopPoint= true;/* see below */
66126629
recoveryContinue= false;
6630+
6631+
/* Exit loop if we reached non-inclusive recovery target */
66136632
if (!recoveryApply)
66146633
break;
66156634
}
@@ -6634,15 +6653,8 @@ StartupXLOG(void)
66346653
*/
66356654
SpinLockAcquire(&xlogctl->info_lck);
66366655
xlogctl->replayEndRecPtr=EndRecPtr;
6637-
recoveryPause=xlogctl->recoveryPause;
66386656
SpinLockRelease(&xlogctl->info_lck);
66396657

6640-
/*
6641-
* Pause only if users can connect to send a resume message
6642-
*/
6643-
if (recoveryPause&&standbyState==STANDBY_SNAPSHOT_READY)
6644-
recoveryPausesHere();
6645-
66466658
/*
66476659
* If we are attempting to enter Hot Standby mode, process
66486660
* XIDs we see
@@ -6664,10 +6676,16 @@ StartupXLOG(void)
66646676
xlogctl->recoveryLastRecPtr=EndRecPtr;
66656677
SpinLockRelease(&xlogctl->info_lck);
66666678

6679+
/* Remember this record as the last-applied one */
66676680
LastRec=ReadRecPtr;
66686681

6682+
/* Exit loop if we reached inclusive recovery target */
6683+
if (!recoveryContinue)
6684+
break;
6685+
6686+
/* Else, try to fetch the next WAL record */
66696687
record=ReadRecord(NULL,LOG, false);
6670-
}while (record!=NULL&&recoveryContinue);
6688+
}while (record!=NULL);
66716689

66726690
/*
66736691
* end of main redo apply loop

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp