You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-05 00:28:52 +02:00
Add timeline and checkpoint checks to backup.
Add the following checks: * Checkpoint is updated in pg_control after pg_start_backup(). This helps ensure that PostgreSQL and pgBackRest have a consistent view of the storage and that PGDATA paths match. * Timeline of backup start WAL file matches pg_control. Hard to see how this one could get hit, but we have the power... * Standby is on the same timeline as the primary. If not, this standby is not following the primary. * Last standby checkpoint is not greater than the backup checkpoint. If so, this standby is not following the primary. This also requires some additional plumbing to read/write timeline/checkpoint from pg_control and parse timelines from WAL filenames. There were some changes in the backup tests caused by the fact that pg_control now has different contents for each backup. The check to ensure that the required checkpoint was reached on the standby should also be updated to use pg_control (it currently uses pg_control_checkpoint()), but that requires non-trivial changes to the test harness and will need to wait.
This commit is contained in:
@ -540,6 +540,25 @@ pgLsnFromWalSegment(const String *walSegment, unsigned int walSegmentSize)
|
||||
(cvtZToUInt64Base(strZ(strSubN(walSegment, 16, 8)), 16) * walSegmentSize));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
uint32_t
|
||||
pgTimelineFromWalSegment(const String *const walSegment)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(STRING, walSegment);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(walSegment != NULL);
|
||||
ASSERT(strSize(walSegment) == 24);
|
||||
|
||||
char buffer[9];
|
||||
|
||||
strncpy(buffer, strZ(walSegment), sizeof(buffer) - 1);
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
|
||||
FUNCTION_TEST_RETURN(cvtZToUIntBase(buffer, 16));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
StringList *
|
||||
pgLsnRangeToWalSegmentList(
|
||||
|
@ -105,6 +105,9 @@ typedef struct PgControl
|
||||
uint64_t systemId;
|
||||
unsigned int catalogVersion;
|
||||
|
||||
uint64_t checkpoint; // Last checkpoint LSN
|
||||
uint32_t timeline; // Current timeline
|
||||
|
||||
unsigned int pageSize;
|
||||
unsigned int walSegmentSize;
|
||||
|
||||
@ -149,6 +152,9 @@ String *pgLsnToStr(uint64_t lsn);
|
||||
String *pgLsnToWalSegment(uint32_t timeline, uint64_t lsn, unsigned int walSegmentSize);
|
||||
uint64_t pgLsnFromWalSegment(const String *walSegment, unsigned int walSegmentSize);
|
||||
|
||||
// Get timeline from WAL segment name
|
||||
uint32_t pgTimelineFromWalSegment(const String *walSegment);
|
||||
|
||||
// Convert a timeline and lsn range to a list of wal segments
|
||||
StringList *pgLsnRangeToWalSegmentList(
|
||||
unsigned int pgVersion, uint32_t timeline, uint64_t lsnStart, uint64_t lsnStop, unsigned int walSegmentSize);
|
||||
|
@ -73,6 +73,8 @@ Read the version specific pg_control into a general data structure
|
||||
{ \
|
||||
.systemId = ((ControlFileData *)controlFile)->system_identifier, \
|
||||
.catalogVersion = ((ControlFileData *)controlFile)->catalog_version_no, \
|
||||
.checkpoint = ((ControlFileData *)controlFile)->checkPoint, \
|
||||
.timeline = ((ControlFileData *)controlFile)->checkPointCopy.ThisTimeLineID, \
|
||||
.pageSize = ((ControlFileData *)controlFile)->blcksz, \
|
||||
.walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \
|
||||
.pageChecksum = ((ControlFileData *)controlFile)->data_checksum_version != 0, \
|
||||
@ -92,6 +94,10 @@ Read the version specific pg_control into a general data structure
|
||||
{ \
|
||||
.systemId = ((ControlFileData *)controlFile)->system_identifier, \
|
||||
.catalogVersion = ((ControlFileData *)controlFile)->catalog_version_no, \
|
||||
.checkpoint = \
|
||||
(uint64_t)((ControlFileData *)controlFile)->checkPoint.xlogid << 32 | \
|
||||
((ControlFileData *)controlFile)->checkPoint.xrecoff, \
|
||||
.timeline = ((ControlFileData *)controlFile)->checkPointCopy.ThisTimeLineID, \
|
||||
.pageSize = ((ControlFileData *)controlFile)->blcksz, \
|
||||
.walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \
|
||||
}; \
|
||||
|
Reference in New Issue
Block a user