mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-29 21:47:21 +02:00
Move standby timeline check after checkpoint.
The standby timeline check was being performed using pg_control data loaded before the backup started. If the backup was started immediately after a promotion the standby might not have executed a checkpoint and written the new timeline to pg_control. Instead perform the timeline check after the checkpoint is executed. This should ensure that the new timeline is in pg_control.
This commit is contained in:
parent
cbbe93f592
commit
c267ba51b1
@ -17,6 +17,19 @@
|
||||
<release date="XXXX-XX-XX" version="2.41dev" title="UNDER DEVELOPMENT">
|
||||
<release-core-list>
|
||||
<release-improvement-list>
|
||||
<release-item>
|
||||
<github-issue id="1816"/>
|
||||
<github-pull-request id="1819"/>
|
||||
|
||||
<release-item-contributor-list>
|
||||
<release-item-ideator id="keith.fiske"/>
|
||||
<release-item-contributor id="david.steele"/>
|
||||
<release-item-reviewer id="stefan.fercot"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Move standby timeline check after checkpoint.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<release-item-contributor-list>
|
||||
<release-item-ideator id="cynthia.shang"/>
|
||||
|
10
src/db/db.c
10
src/db/db.c
@ -610,9 +610,6 @@ dbReplayWait(Db *const this, const String *const targetLsn, const uint32_t targe
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
{
|
||||
// Check that the timeline matches the primary
|
||||
if (dbPgControl(this).timeline != targetTimeline)
|
||||
THROW_FMT(DbMismatchError, "standby is on timeline %u but expected %u", dbPgControl(this).timeline, targetTimeline);
|
||||
|
||||
// Standby checkpoint before the backup started must be <= the target LSN. If not, it indicates that the standby was ahead
|
||||
// of the primary and cannot be following it.
|
||||
@ -727,6 +724,13 @@ dbReplayWait(Db *const this, const String *const targetLsn, const uint32_t targe
|
||||
strZ(checkpointLsn));
|
||||
}
|
||||
}
|
||||
|
||||
// Reload pg_control in case timeline was updated by the checkpoint
|
||||
this->pub.pgControl = pgControlFromFile(this->storage);
|
||||
|
||||
// Check that the timeline matches the primary
|
||||
if (dbPgControl(this).timeline != targetTimeline)
|
||||
THROW_FMT(DbMismatchError, "standby is on timeline %u but expected %u", dbPgControl(this).timeline, targetTimeline);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
|
@ -588,6 +588,14 @@ testRun(void)
|
||||
HRNPQ_MACRO_CHECKPOINT(2),
|
||||
HRNPQ_MACRO_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", true, "X/X", 0),
|
||||
|
||||
// Fail on timeline mismatch
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_GE_10(2, "5/5", false, "5/3"),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/3", "5/3", false, 0),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", false, "5/4", "5/3", true, 0),
|
||||
HRNPQ_MACRO_REPLAY_TARGET_REACHED_PROGRESS_GE_10(2, "5/5", true, "5/5", "5/4", true, 0),
|
||||
HRNPQ_MACRO_CHECKPOINT(2),
|
||||
HRNPQ_MACRO_CHECKPOINT_TARGET_REACHED_GE_10(2, "5/5", true, "X/X", 0),
|
||||
|
||||
// Close standby
|
||||
HRNPQ_MACRO_CLOSE(2),
|
||||
|
||||
@ -610,8 +618,6 @@ testRun(void)
|
||||
TEST_RESULT_STR_Z(backupStartResult.walSegmentName, "000000050000000500000005", "check wal segment name");
|
||||
TEST_RESULT_STR_Z(backupStartResult.walSegmentCheck, "000000050000000500000005", "check wal segment check");
|
||||
|
||||
TEST_ERROR(
|
||||
dbReplayWait(db.standby, STRDEF("5/5"), 77, 1000), DbMismatchError, "standby is on timeline 5 but expected 77");
|
||||
TEST_ERROR(
|
||||
dbReplayWait(db.standby, STRDEF("4/4"), 5, 1000), DbMismatchError, "standby checkpoint '5/5' is ahead of target '4/4'");
|
||||
|
||||
@ -632,6 +638,12 @@ testRun(void)
|
||||
|
||||
TEST_RESULT_VOID(dbReplayWait(db.standby, STRDEF("5/5"), dbPgControl(db.primary).timeline, 1000), "sync standby");
|
||||
|
||||
// Update timeline to demonstrate that it is reloaded in dbReplayWait()
|
||||
HRN_PG_CONTROL_PUT(storagePgIdxWrite(1), PG_VERSION_93, .timeline = 6, .checkpoint = pgLsnFromStr(STRDEF("5/5")));
|
||||
|
||||
TEST_ERROR(
|
||||
dbReplayWait(db.standby, STRDEF("5/5"), 77, 1000), DbMismatchError, "standby is on timeline 6 but expected 77");
|
||||
|
||||
TEST_RESULT_VOID(dbFree(db.standby), "free standby");
|
||||
|
||||
TEST_RESULT_STR_Z(dbBackupStop(db.primary).tablespaceMap, "TABLESPACE_MAP_DATA", "stop backup");
|
||||
|
Loading…
x
Reference in New Issue
Block a user