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

Commit5840e31

Browse files
committed
Consistency check should compare last record replayed, not last record read.
EndRecPtr is the last record that we've read, but not necessarily yetreplayed. CheckRecoveryConsistency should compare minRecoveryPoint with thelast replayed record instead. This caused recovery to think it's reachedconsistency too early.Now that we do the check in CheckRecoveryConsistency correctly, we have tomove the call of that function to after redoing a record. The current place,after reading a record but before replaying it, is wrong. In particular, ifthere are no more records after the one ending at minRecoveryPoint, we don'tenter hot standby until one extra record is generated and read by thestandby, and CheckRecoveryConsistency is called. These two bugs conspiredto make the code appear to work correctly, except for the small windowbetween reading the last record that reaches minRecoveryPoint, andreplaying it.In the passing, rename recoveryLastRecPtr, which is the last recordreplayed, to lastReplayedEndRecPtr. This makes it slightly less confusingwith replayEndRecPtr, which is the last record read that we're about toreplay.Original report from Kyotaro HORIGUCHI, further diagnosis by Fujii Masao.Backpatch to 9.0, where Hot Standby subtly changed the test from"minRecoveryPoint < EndRecPtr" to "minRecoveryPoint <= EndRecPtr". Theformer works because where the test is performed, we have always read onemore record than we've replayed.
1 parentfe20ff0 commit5840e31

File tree

1 file changed

+19
-14
lines changed
  • src/backend/access/transam

1 file changed

+19
-14
lines changed

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

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,14 @@ typedef struct XLogCtlData
402402
XLogRecPtrlastCheckPointRecPtr;
403403
CheckPointlastCheckPoint;
404404

405-
/* end+1 of the last record replayed (or being replayed) */
405+
/*
406+
* lastReplayedEndRecPtr points to end+1 of the last record successfully
407+
* replayed. When we're currently replaying a record, ie. in a redo
408+
* function, replayEndRecPtr points to the end+1 of the record being
409+
* replayed, otherwise it's equal to lastReplayedEndRecPtr.
410+
*/
411+
XLogRecPtrlastReplayedEndRecPtr;
406412
XLogRecPtrreplayEndRecPtr;
407-
/* end+1 of the last record replayed */
408-
XLogRecPtrrecoveryLastRecPtr;
409413
/* timestamp of last COMMIT/ABORT record replayed (or being replayed) */
410414
TimestampTzrecoveryLastXTime;
411415

@@ -6161,7 +6165,7 @@ StartupXLOG(void)
61616165
}
61626166

61636167
/*
6164-
* Initialize shared replayEndRecPtr,recoveryLastRecPtr, and
6168+
* Initialize shared replayEndRecPtr,lastReplayedEndRecPtr, and
61656169
* recoveryLastXTime.
61666170
*
61676171
* This is slightly confusing if we're starting from an online
@@ -6174,7 +6178,7 @@ StartupXLOG(void)
61746178
*/
61756179
SpinLockAcquire(&xlogctl->info_lck);
61766180
xlogctl->replayEndRecPtr=ReadRecPtr;
6177-
xlogctl->recoveryLastRecPtr=EndRecPtr;
6181+
xlogctl->lastReplayedEndRecPtr=EndRecPtr;
61786182
xlogctl->recoveryLastXTime=0;
61796183
SpinLockRelease(&xlogctl->info_lck);
61806184

@@ -6263,9 +6267,6 @@ StartupXLOG(void)
62636267
/* Handle interrupt signals of startup process */
62646268
HandleStartupProcInterrupts();
62656269

6266-
/* Allow read-only connections if we're consistent now */
6267-
CheckRecoveryConsistency();
6268-
62696270
/*
62706271
* Have we reached our recovery target?
62716272
*/
@@ -6313,15 +6314,18 @@ StartupXLOG(void)
63136314
error_context_stack=errcontext.previous;
63146315

63156316
/*
6316-
* Updateshared recoveryLastRecPtr after this record has been
6317-
* replayed.
6317+
* UpdatelastReplayedEndRecPtr after this record has been
6318+
*successfullyreplayed.
63186319
*/
63196320
SpinLockAcquire(&xlogctl->info_lck);
6320-
xlogctl->recoveryLastRecPtr=EndRecPtr;
6321+
xlogctl->lastReplayedEndRecPtr=EndRecPtr;
63216322
SpinLockRelease(&xlogctl->info_lck);
63226323

63236324
LastRec=ReadRecPtr;
63246325

6326+
/* Allow read-only connections if we're consistent now */
6327+
CheckRecoveryConsistency();
6328+
63256329
record=ReadRecord(NULL,LOG, false);
63266330
}while (record!=NULL&&recoveryContinue);
63276331

@@ -6661,13 +6665,14 @@ CheckRecoveryConsistency(void)
66616665
* Have we passed our safe starting point?
66626666
*/
66636667
if (!reachedConsistency&&
6664-
XLByteLE(minRecoveryPoint,EndRecPtr)&&
6668+
XLByteLE(minRecoveryPoint,XLogCtl->lastReplayedEndRecPtr)&&
66656669
XLogRecPtrIsInvalid(ControlFile->backupStartPoint))
66666670
{
66676671
reachedConsistency= true;
66686672
ereport(LOG,
66696673
(errmsg("consistent recovery state reached at %X/%X",
6670-
EndRecPtr.xlogid,EndRecPtr.xrecoff)));
6674+
XLogCtl->lastReplayedEndRecPtr.xlogid,
6675+
XLogCtl->lastReplayedEndRecPtr.xrecoff)));
66716676
}
66726677

66736678
/*
@@ -8967,7 +8972,7 @@ pg_last_xlog_replay_location(PG_FUNCTION_ARGS)
89678972
charlocation[MAXFNAMELEN];
89688973

89698974
SpinLockAcquire(&xlogctl->info_lck);
8970-
recptr=xlogctl->recoveryLastRecPtr;
8975+
recptr=xlogctl->lastReplayedEndRecPtr;
89718976
SpinLockRelease(&xlogctl->info_lck);
89728977

89738978
if (recptr.xlogid==0&&recptr.xrecoff==0)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp