1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-03 00:26:59 +02:00

Improve PostgreSQL version identification.

Previously, catalog versions were fixed for all versions which made maintaining the catalog versions during PostgreSQL beta and release candidate cycles very painful. A version of pgBackRest which was functionally compatible was rendered useless by a catalog version bump in PostgreSQL.

Instead use only the control version to identify a PostgreSQL version when possible. Some older versions require a catalog version to positively identify a PostgreSQL version, so include them when required.

Since the catalog number is required to work with tablespaces it will need to be stored. There's already a copy of it in backup.info so use that (even though we have been ignoring it in the C versions).
This commit is contained in:
David Steele
2020-09-18 16:55:26 -04:00
committed by GitHub
parent 94475bfbe6
commit 927d9adbee
26 changed files with 259 additions and 270 deletions

View File

@ -37,6 +37,16 @@
<p>Ignore <file>backup_manifest</file> in <postgres/> 13.</p> <p>Ignore <file>backup_manifest</file> in <postgres/> 13.</p>
</release-item> </release-item>
<release-item>
<release-item-contributor-list>
<release-item-contributor id="david.steele"/>
<release-item-reviewer id="cynthia.shang"/>
<release-item-reviewer id="stephen.frost"/>
</release-item-contributor-list>
<p>Improve <postgres/> version identification.</p>
</release-item>
<release-item> <release-item>
<release-item-contributor-list> <release-item-contributor-list>
<release-item-contributor id="david.steele"/> <release-item-contributor id="david.steele"/>

View File

@ -1947,8 +1947,8 @@ cmdBackup(void)
// Build the manifest // Build the manifest
Manifest *manifest = manifestNewBuild( Manifest *manifest = manifestNewBuild(
backupData->storagePrimary, infoPg.version, cfgOptionBool(cfgOptOnline), cfgOptionBool(cfgOptChecksumPage), backupData->storagePrimary, infoPg.version, infoPg.catalogVersion, cfgOptionBool(cfgOptOnline),
strLstNewVarLst(cfgOptionLst(cfgOptExclude)), backupStartResult.tablespaceList); cfgOptionBool(cfgOptChecksumPage), strLstNewVarLst(cfgOptionLst(cfgOptExclude)), backupStartResult.tablespaceList);
// Validate the manifest using the copy start time // Validate the manifest using the copy start time
manifestBuildValidate( manifestBuildValidate(

View File

@ -933,7 +933,8 @@ restoreCleanBuild(Manifest *manifest)
// If this is a tablespace append the tablespace identifier // If this is a tablespace append the tablespace identifier
if (cleanData->target->type == manifestTargetTypeLink && cleanData->target->tablespaceId != 0) if (cleanData->target->type == manifestTargetTypeLink && cleanData->target->tablespaceId != 0)
{ {
const String *tablespaceId = pgTablespaceId(manifestData(manifest)->pgVersion); const String *tablespaceId = pgTablespaceId(
manifestData(manifest)->pgVersion, manifestData(manifest)->pgCatalogVersion);
// Only PostgreSQL >= 9.0 has tablespace indentifiers // Only PostgreSQL >= 9.0 has tablespace indentifiers
if (tablespaceId != NULL) if (tablespaceId != NULL)
@ -1181,7 +1182,8 @@ restoreSelectiveExpression(Manifest *manifest)
// Generate tablespace expression // Generate tablespace expression
RegExp *tablespaceRegExp = NULL; RegExp *tablespaceRegExp = NULL;
const String *tablespaceId = pgTablespaceId(manifestData(manifest)->pgVersion); const String *tablespaceId = pgTablespaceId(
manifestData(manifest)->pgVersion, manifestData(manifest)->pgCatalogVersion);
if (tablespaceId == NULL) if (tablespaceId == NULL)
tablespaceRegExp = regExpNew(STRDEF("^" MANIFEST_TARGET_PGTBLSPC "/[0-9]+/[0-9]+/" PG_FILE_PGVERSION)); tablespaceRegExp = regExpNew(STRDEF("^" MANIFEST_TARGET_PGTBLSPC "/[0-9]+/[0-9]+/" PG_FILE_PGVERSION));

View File

@ -80,7 +80,7 @@ cmdStanzaCreate(void)
cipherPassSub = cipherPassGen(cipherType(cfgOptionStr(cfgOptRepoCipherType))); cipherPassSub = cipherPassGen(cipherType(cfgOptionStr(cfgOptRepoCipherType)));
// Create and save backup info // Create and save backup info
infoBackup = infoBackupNew(pgControl.version, pgControl.systemId, cipherPassSub); infoBackup = infoBackupNew(pgControl.version, pgControl.systemId, pgControl.catalogVersion, cipherPassSub);
infoBackupSaveFile( infoBackupSaveFile(
infoBackup, storageRepoWriteStanza, INFO_BACKUP_PATH_FILE_STR, cipherType(cfgOptionStr(cfgOptRepoCipherType)), infoBackup, storageRepoWriteStanza, INFO_BACKUP_PATH_FILE_STR, cipherType(cfgOptionStr(cfgOptRepoCipherType)),

View File

@ -65,7 +65,7 @@ cmdStanzaUpgrade(void)
// Update backup // Update backup
if (pgControl.version != backupInfo.version || pgControl.systemId != backupInfo.systemId) if (pgControl.version != backupInfo.version || pgControl.systemId != backupInfo.systemId)
{ {
infoBackupPgSet(infoBackup, pgControl.version, pgControl.systemId); infoBackupPgSet(infoBackup, pgControl.version, pgControl.systemId, pgControl.catalogVersion);
infoBackupUpgrade = true; infoBackupUpgrade = true;
} }

View File

@ -236,7 +236,7 @@ infoArchivePgSet(InfoArchive *this, unsigned int pgVersion, uint64_t pgSystemId)
ASSERT(this != NULL); ASSERT(this != NULL);
this->infoPg = infoPgSet(this->infoPg, infoPgArchive, pgVersion, pgSystemId); this->infoPg = infoPgSet(this->infoPg, infoPgArchive, pgVersion, pgSystemId, 0);
FUNCTION_LOG_RETURN(INFO_ARCHIVE, this); FUNCTION_LOG_RETURN(INFO_ARCHIVE, this);
} }

View File

@ -88,15 +88,16 @@ infoBackupNewInternal(void)
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
InfoBackup * InfoBackup *
infoBackupNew(unsigned int pgVersion, uint64_t pgSystemId, const String *cipherPassSub) infoBackupNew(unsigned int pgVersion, uint64_t pgSystemId, unsigned int pgCatalogVersion, const String *cipherPassSub)
{ {
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(UINT, pgVersion); FUNCTION_LOG_PARAM(UINT, pgVersion);
FUNCTION_LOG_PARAM(UINT64, pgSystemId); FUNCTION_LOG_PARAM(UINT64, pgSystemId);
FUNCTION_LOG_PARAM(UINT, pgCatalogVersion);
FUNCTION_TEST_PARAM(STRING, cipherPassSub); FUNCTION_TEST_PARAM(STRING, cipherPassSub);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(pgVersion > 0 && pgSystemId > 0); ASSERT(pgVersion > 0 && pgSystemId > 0 && pgCatalogVersion > 0);
InfoBackup *this = NULL; InfoBackup *this = NULL;
@ -106,7 +107,7 @@ infoBackupNew(unsigned int pgVersion, uint64_t pgSystemId, const String *cipherP
// Initialize the pg data // Initialize the pg data
this->infoPg = infoPgNew(infoPgBackup, cipherPassSub); this->infoPg = infoPgNew(infoPgBackup, cipherPassSub);
infoBackupPgSet(this, pgVersion, pgSystemId); infoBackupPgSet(this, pgVersion, pgSystemId, pgCatalogVersion);
} }
MEM_CONTEXT_NEW_END(); MEM_CONTEXT_NEW_END();
@ -307,15 +308,16 @@ infoBackupPg(const InfoBackup *this)
} }
InfoBackup * InfoBackup *
infoBackupPgSet(InfoBackup *this, unsigned int pgVersion, uint64_t pgSystemId) infoBackupPgSet(InfoBackup *this, unsigned int pgVersion, uint64_t pgSystemId, unsigned int pgCatalogVersion)
{ {
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(INFO_BACKUP, this); FUNCTION_LOG_PARAM(INFO_BACKUP, this);
FUNCTION_LOG_PARAM(UINT, pgVersion); FUNCTION_LOG_PARAM(UINT, pgVersion);
FUNCTION_LOG_PARAM(UINT64, pgSystemId); FUNCTION_LOG_PARAM(UINT64, pgSystemId);
FUNCTION_LOG_PARAM(UINT, pgCatalogVersion);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
this->infoPg = infoPgSet(this->infoPg, infoPgBackup, pgVersion, pgSystemId); this->infoPg = infoPgSet(this->infoPg, infoPgBackup, pgVersion, pgSystemId, pgCatalogVersion);
FUNCTION_LOG_RETURN(INFO_BACKUP, this); FUNCTION_LOG_RETURN(INFO_BACKUP, this);
} }

View File

@ -60,7 +60,7 @@ typedef struct InfoBackupData
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Constructors Constructors
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
InfoBackup *infoBackupNew(unsigned int pgVersion, uint64_t pgSystemId, const String *cipherPassSub); InfoBackup *infoBackupNew(unsigned int pgVersion, uint64_t pgSystemId, unsigned int pgCatalogVersion, const String *cipherPassSub);
// Create new object and load contents from IoRead // Create new object and load contents from IoRead
InfoBackup *infoBackupNewLoad(IoRead *read); InfoBackup *infoBackupNewLoad(IoRead *read);
@ -85,7 +85,7 @@ StringList *infoBackupDataLabelList(const InfoBackup *this, const String *expres
// PostgreSQL info // PostgreSQL info
InfoPg *infoBackupPg(const InfoBackup *this); InfoPg *infoBackupPg(const InfoBackup *this);
InfoBackup *infoBackupPgSet(InfoBackup *this, unsigned int pgVersion, uint64_t pgSystemId); InfoBackup *infoBackupPgSet(InfoBackup *this, unsigned int pgVersion, uint64_t pgSystemId, unsigned int pgCatalogVersion);
// Return a structure of the backup data from a specific index // Return a structure of the backup data from a specific index
InfoBackupData infoBackupData(const InfoBackup *this, unsigned int backupDataIdx); InfoBackupData infoBackupData(const InfoBackup *this, unsigned int backupDataIdx);

View File

@ -133,6 +133,8 @@ infoPgLoadCallback(void *data, const String *section, const String *key, const V
{ {
.id = cvtZToUInt(strZ(key)), .id = cvtZToUInt(strZ(key)),
.version = pgVersionFromStr(varStr(kvGet(pgDataKv, INFO_KEY_DB_VERSION_VAR))), .version = pgVersionFromStr(varStr(kvGet(pgDataKv, INFO_KEY_DB_VERSION_VAR))),
.catalogVersion =
loadData->infoPg->type == infoPgBackup ? varUIntForce(kvGet(pgDataKv, INFO_KEY_DB_CATALOG_VERSION_VAR)) : 0,
// This is different in archive.info due to a typo that can't be fixed without a format version bump // This is different in archive.info due to a typo that can't be fixed without a format version bump
.systemId = varUInt64Force( .systemId = varUInt64Force(
@ -223,13 +225,15 @@ infoPgAdd(InfoPg *this, const InfoPgData *infoPgData)
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
InfoPg * InfoPg *
infoPgSet(InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId) infoPgSet(
InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId, const unsigned int pgCatalogVersion)
{ {
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(INFO_PG, this); FUNCTION_LOG_PARAM(INFO_PG, this);
FUNCTION_LOG_PARAM(ENUM, type); FUNCTION_LOG_PARAM(ENUM, type);
FUNCTION_LOG_PARAM(UINT, pgVersion); FUNCTION_LOG_PARAM(UINT, pgVersion);
FUNCTION_LOG_PARAM(UINT64, pgSystemId); FUNCTION_LOG_PARAM(UINT64, pgSystemId);
FUNCTION_LOG_PARAM(UINT, pgCatalogVersion);
FUNCTION_LOG_END(); FUNCTION_LOG_END();
ASSERT(this != NULL); ASSERT(this != NULL);
@ -250,6 +254,9 @@ infoPgSet(InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uin
// This is different in archive.info due to a typo that can't be fixed without a format version bump // This is different in archive.info due to a typo that can't be fixed without a format version bump
.systemId = pgSystemId, .systemId = pgSystemId,
// Catalog version is only required for backup info to preserve the repo format
.catalogVersion = this->type == infoPgBackup ? pgCatalogVersion : 0,
}; };
// Add the pg data to the history list // Add the pg data to the history list
@ -294,8 +301,7 @@ infoPgSaveCallback(void *data, const String *sectionNext, InfoSave *infoSaveData
if (saveData->infoPg->type == infoPgBackup) if (saveData->infoPg->type == infoPgBackup)
{ {
infoSaveValue( infoSaveValue(
infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_CATALOG_VERSION_VAR), infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_CATALOG_VERSION_VAR), jsonFromUInt(pgData.catalogVersion));
jsonFromUInt(pgCatalogVersion(pgData.version)));
infoSaveValue( infoSaveValue(
infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_CONTROL_VERSION_VAR), infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_CONTROL_VERSION_VAR),
jsonFromUInt(pgControlVersion(pgData.version))); jsonFromUInt(pgControlVersion(pgData.version)));
@ -325,7 +331,7 @@ infoPgSaveCallback(void *data, const String *sectionNext, InfoSave *infoSaveData
kvPut(pgDataKv, INFO_KEY_DB_SYSTEM_ID_VAR, VARUINT64(pgData.systemId)); kvPut(pgDataKv, INFO_KEY_DB_SYSTEM_ID_VAR, VARUINT64(pgData.systemId));
// These need to be saved because older pgBackRest versions expect them // These need to be saved because older pgBackRest versions expect them
kvPut(pgDataKv, INFO_KEY_DB_CATALOG_VERSION_VAR, VARUINT(pgCatalogVersion(pgData.version))); kvPut(pgDataKv, INFO_KEY_DB_CATALOG_VERSION_VAR, VARUINT(pgData.catalogVersion));
kvPut(pgDataKv, INFO_KEY_DB_CONTROL_VERSION_VAR, VARUINT(pgControlVersion(pgData.version))); kvPut(pgDataKv, INFO_KEY_DB_CONTROL_VERSION_VAR, VARUINT(pgControlVersion(pgData.version)));
} }
else else
@ -486,5 +492,7 @@ infoPgCurrentDataId(const InfoPg *this)
String * String *
infoPgDataToLog(const InfoPgData *this) infoPgDataToLog(const InfoPgData *this)
{ {
return strNewFmt("{id: %u, version: %u, systemId: %" PRIu64 "}", this->id, this->version, this->systemId); return strNewFmt(
"{id: %u, version: %u, systemId: %" PRIu64 ", catalogVersion: %u}", this->id, this->version, this->systemId,
this->catalogVersion);
} }

View File

@ -32,6 +32,7 @@ typedef struct InfoPgData
{ {
unsigned int id; unsigned int id;
uint64_t systemId; uint64_t systemId;
unsigned int catalogVersion;
unsigned int version; unsigned int version;
} InfoPgData; } InfoPgData;
@ -62,7 +63,8 @@ void infoPgAdd(InfoPg *this, const InfoPgData *infoPgData);
void infoPgSave(InfoPg *this, IoWrite *write, InfoSaveCallback *callbackFunction, void *callbackData); void infoPgSave(InfoPg *this, IoWrite *write, InfoSaveCallback *callbackFunction, void *callbackData);
// Set the InfoPg object data based on values passed // Set the InfoPg object data based on values passed
InfoPg *infoPgSet(InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId); InfoPg *infoPgSet(
InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId, const unsigned int pgCatalogVersion);
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Getters/Setters Getters/Setters

View File

@ -75,6 +75,8 @@ STRING_STATIC(MANIFEST_SECTION_TARGET_PATH_DEFAULT_STR, "target:path
VARIANT_STRDEF_STATIC(MANIFEST_KEY_CHECKSUM_PAGE_VAR, MANIFEST_KEY_CHECKSUM_PAGE); VARIANT_STRDEF_STATIC(MANIFEST_KEY_CHECKSUM_PAGE_VAR, MANIFEST_KEY_CHECKSUM_PAGE);
#define MANIFEST_KEY_CHECKSUM_PAGE_ERROR "checksum-page-error" #define MANIFEST_KEY_CHECKSUM_PAGE_ERROR "checksum-page-error"
VARIANT_STRDEF_STATIC(MANIFEST_KEY_CHECKSUM_PAGE_ERROR_VAR, MANIFEST_KEY_CHECKSUM_PAGE_ERROR); VARIANT_STRDEF_STATIC(MANIFEST_KEY_CHECKSUM_PAGE_ERROR_VAR, MANIFEST_KEY_CHECKSUM_PAGE_ERROR);
#define MANIFEST_KEY_DB_CATALOG_VERSION "db-catalog-version"
STRING_STATIC(MANIFEST_KEY_DB_CATALOG_VERSION_STR, MANIFEST_KEY_DB_CATALOG_VERSION);
#define MANIFEST_KEY_DB_ID "db-id" #define MANIFEST_KEY_DB_ID "db-id"
STRING_STATIC(MANIFEST_KEY_DB_ID_STR, MANIFEST_KEY_DB_ID); STRING_STATIC(MANIFEST_KEY_DB_ID_STR, MANIFEST_KEY_DB_ID);
VARIANT_STRDEF_STATIC(MANIFEST_KEY_DB_ID_VAR, MANIFEST_KEY_DB_ID); VARIANT_STRDEF_STATIC(MANIFEST_KEY_DB_ID_VAR, MANIFEST_KEY_DB_ID);
@ -853,12 +855,13 @@ manifestBuildCallback(void *data, const StorageInfo *info)
Manifest * Manifest *
manifestNewBuild( manifestNewBuild(
const Storage *storagePg, unsigned int pgVersion, bool online, bool checksumPage, const StringList *excludeList, const Storage *storagePg, unsigned int pgVersion, unsigned int pgCatalogVersion, bool online, bool checksumPage,
const VariantList *tablespaceList) const StringList *excludeList, const VariantList *tablespaceList)
{ {
FUNCTION_LOG_BEGIN(logLevelDebug); FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(STORAGE, storagePg); FUNCTION_LOG_PARAM(STORAGE, storagePg);
FUNCTION_LOG_PARAM(UINT, pgVersion); FUNCTION_LOG_PARAM(UINT, pgVersion);
FUNCTION_LOG_PARAM(UINT, pgCatalogVersion);
FUNCTION_LOG_PARAM(BOOL, online); FUNCTION_LOG_PARAM(BOOL, online);
FUNCTION_LOG_PARAM(BOOL, checksumPage); FUNCTION_LOG_PARAM(BOOL, checksumPage);
FUNCTION_LOG_PARAM(STRING_LIST, excludeList); FUNCTION_LOG_PARAM(STRING_LIST, excludeList);
@ -877,6 +880,7 @@ manifestNewBuild(
this->info = infoNew(NULL); this->info = infoNew(NULL);
this->data.backrestVersion = strNew(PROJECT_VERSION); this->data.backrestVersion = strNew(PROJECT_VERSION);
this->data.pgVersion = pgVersion; this->data.pgVersion = pgVersion;
this->data.pgCatalogVersion = pgCatalogVersion;
this->data.backupOptionOnline = online; this->data.backupOptionOnline = online;
this->data.backupOptionChecksumPage = varNewBool(checksumPage); this->data.backupOptionChecksumPage = varNewBool(checksumPage);
@ -887,7 +891,7 @@ manifestNewBuild(
{ {
.manifest = this, .manifest = this,
.storagePg = storagePg, .storagePg = storagePg,
.tablespaceId = pgTablespaceId(pgVersion), .tablespaceId = pgTablespaceId(pgVersion, pgCatalogVersion),
.online = online, .online = online,
.checksumPage = checksumPage, .checksumPage = checksumPage,
.tablespaceList = tablespaceList, .tablespaceList = tablespaceList,
@ -1679,6 +1683,8 @@ manifestLoadCallback(void *callbackData, const String *section, const String *ke
manifest->data.pgId = varUIntForce(value); manifest->data.pgId = varUIntForce(value);
else if (strEq(key, MANIFEST_KEY_DB_SYSTEM_ID_STR)) else if (strEq(key, MANIFEST_KEY_DB_SYSTEM_ID_STR))
manifest->data.pgSystemId = varUInt64(value); manifest->data.pgSystemId = varUInt64(value);
else if (strEq(key, MANIFEST_KEY_DB_CATALOG_VERSION_STR))
manifest->data.pgCatalogVersion = varUIntForce(value);
else if (strEq(key, MANIFEST_KEY_DB_VERSION_STR)) else if (strEq(key, MANIFEST_KEY_DB_VERSION_STR))
manifest->data.pgVersion = pgVersionFromStr(varStr(value)); manifest->data.pgVersion = pgVersionFromStr(varStr(value));
} }
@ -1934,8 +1940,8 @@ manifestSaveCallback(void *callbackData, const String *sectionNext, InfoSave *in
if (infoSaveSection(infoSaveData, MANIFEST_SECTION_BACKUP_DB_STR, sectionNext)) if (infoSaveSection(infoSaveData, MANIFEST_SECTION_BACKUP_DB_STR, sectionNext))
{ {
infoSaveValue( infoSaveValue(
infoSaveData, MANIFEST_SECTION_BACKUP_DB_STR, STRDEF("db-catalog-version"), infoSaveData, MANIFEST_SECTION_BACKUP_DB_STR, MANIFEST_KEY_DB_CATALOG_VERSION_STR,
jsonFromUInt(pgCatalogVersion(manifest->data.pgVersion))); jsonFromUInt(manifest->data.pgCatalogVersion));
infoSaveValue( infoSaveValue(
infoSaveData, MANIFEST_SECTION_BACKUP_DB_STR, STRDEF("db-control-version"), infoSaveData, MANIFEST_SECTION_BACKUP_DB_STR, STRDEF("db-control-version"),
jsonFromUInt(pgControlVersion(manifest->data.pgVersion))); jsonFromUInt(pgControlVersion(manifest->data.pgVersion)));

View File

@ -61,6 +61,7 @@ typedef struct ManifestData
unsigned int pgId; // PostgreSQL id in backup.info unsigned int pgId; // PostgreSQL id in backup.info
unsigned int pgVersion; // PostgreSQL version unsigned int pgVersion; // PostgreSQL version
uint64_t pgSystemId; // PostgreSQL system identifier uint64_t pgSystemId; // PostgreSQL system identifier
unsigned int pgCatalogVersion; // PostgreSQL catalog version
bool backupOptionArchiveCheck; // Will WAL segments be checked at the end of the backup? bool backupOptionArchiveCheck; // Will WAL segments be checked at the end of the backup?
bool backupOptionArchiveCopy; // Will WAL segments be copied to the backup? bool backupOptionArchiveCopy; // Will WAL segments be copied to the backup?
@ -152,8 +153,8 @@ Constructors
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
// Build a new manifest for a PostgreSQL data directory // Build a new manifest for a PostgreSQL data directory
Manifest *manifestNewBuild( Manifest *manifestNewBuild(
const Storage *storagePg, unsigned int pgVersion, bool online, bool checksumPage, const StringList *excludeList, const Storage *storagePg, unsigned int pgVersion, unsigned int pgCatalogVersion, bool online, bool checksumPage,
const VariantList *tablespaceList); const StringList *excludeList, const VariantList *tablespaceList);
// Load a manifest from IO // Load a manifest from IO
Manifest *manifestNewLoad(IoRead *read); Manifest *manifestNewLoad(IoRead *read);

View File

@ -66,9 +66,6 @@ typedef struct PgInterface
// Version of PostgreSQL supported by this interface // Version of PostgreSQL supported by this interface
unsigned int version; unsigned int version;
// Get the catalog version for this version of PostgreSQL
uint32_t (*catalogVersion)(void);
// Does pg_control match this version of PostgreSQL? // Does pg_control match this version of PostgreSQL?
bool (*controlIs)(const unsigned char *); bool (*controlIs)(const unsigned char *);
@ -85,6 +82,8 @@ typedef struct PgInterface
PgWal (*wal)(const unsigned char *); PgWal (*wal)(const unsigned char *);
#ifdef DEBUG #ifdef DEBUG
// Catalog version for testing
unsigned int catalogVersion;
// Create pg_control for testing // Create pg_control for testing
void (*controlTest)(PgControl, unsigned char *); void (*controlTest)(PgControl, unsigned char *);
@ -99,8 +98,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_13, .version = PG_VERSION_13,
.catalogVersion = pgInterfaceCatalogVersion130,
.controlIs = pgInterfaceControlIs130, .controlIs = pgInterfaceControlIs130,
.control = pgInterfaceControl130, .control = pgInterfaceControl130,
.controlVersion = pgInterfaceControlVersion130, .controlVersion = pgInterfaceControlVersion130,
@ -109,6 +106,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal130, .wal = pgInterfaceWal130,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 202007201,
.controlTest = pgInterfaceControlTest130, .controlTest = pgInterfaceControlTest130,
.walTest = pgInterfaceWalTest130, .walTest = pgInterfaceWalTest130,
#endif #endif
@ -116,8 +115,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_12, .version = PG_VERSION_12,
.catalogVersion = pgInterfaceCatalogVersion120,
.controlIs = pgInterfaceControlIs120, .controlIs = pgInterfaceControlIs120,
.control = pgInterfaceControl120, .control = pgInterfaceControl120,
.controlVersion = pgInterfaceControlVersion120, .controlVersion = pgInterfaceControlVersion120,
@ -126,6 +123,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal120, .wal = pgInterfaceWal120,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201909212,
.controlTest = pgInterfaceControlTest120, .controlTest = pgInterfaceControlTest120,
.walTest = pgInterfaceWalTest120, .walTest = pgInterfaceWalTest120,
#endif #endif
@ -133,8 +132,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_11, .version = PG_VERSION_11,
.catalogVersion = pgInterfaceCatalogVersion110,
.controlIs = pgInterfaceControlIs110, .controlIs = pgInterfaceControlIs110,
.control = pgInterfaceControl110, .control = pgInterfaceControl110,
.controlVersion = pgInterfaceControlVersion110, .controlVersion = pgInterfaceControlVersion110,
@ -143,6 +140,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal110, .wal = pgInterfaceWal110,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201809051,
.controlTest = pgInterfaceControlTest110, .controlTest = pgInterfaceControlTest110,
.walTest = pgInterfaceWalTest110, .walTest = pgInterfaceWalTest110,
#endif #endif
@ -150,8 +149,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_10, .version = PG_VERSION_10,
.catalogVersion = pgInterfaceCatalogVersion100,
.controlIs = pgInterfaceControlIs100, .controlIs = pgInterfaceControlIs100,
.control = pgInterfaceControl100, .control = pgInterfaceControl100,
.controlVersion = pgInterfaceControlVersion100, .controlVersion = pgInterfaceControlVersion100,
@ -160,6 +157,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal100, .wal = pgInterfaceWal100,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201707211,
.controlTest = pgInterfaceControlTest100, .controlTest = pgInterfaceControlTest100,
.walTest = pgInterfaceWalTest100, .walTest = pgInterfaceWalTest100,
#endif #endif
@ -167,8 +166,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_96, .version = PG_VERSION_96,
.catalogVersion = pgInterfaceCatalogVersion096,
.controlIs = pgInterfaceControlIs096, .controlIs = pgInterfaceControlIs096,
.control = pgInterfaceControl096, .control = pgInterfaceControl096,
.controlVersion = pgInterfaceControlVersion096, .controlVersion = pgInterfaceControlVersion096,
@ -177,6 +174,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal096, .wal = pgInterfaceWal096,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201608131,
.controlTest = pgInterfaceControlTest096, .controlTest = pgInterfaceControlTest096,
.walTest = pgInterfaceWalTest096, .walTest = pgInterfaceWalTest096,
#endif #endif
@ -184,8 +183,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_95, .version = PG_VERSION_95,
.catalogVersion = pgInterfaceCatalogVersion095,
.controlIs = pgInterfaceControlIs095, .controlIs = pgInterfaceControlIs095,
.control = pgInterfaceControl095, .control = pgInterfaceControl095,
.controlVersion = pgInterfaceControlVersion095, .controlVersion = pgInterfaceControlVersion095,
@ -194,6 +191,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal095, .wal = pgInterfaceWal095,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201510051,
.controlTest = pgInterfaceControlTest095, .controlTest = pgInterfaceControlTest095,
.walTest = pgInterfaceWalTest095, .walTest = pgInterfaceWalTest095,
#endif #endif
@ -201,8 +200,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_94, .version = PG_VERSION_94,
.catalogVersion = pgInterfaceCatalogVersion094,
.controlIs = pgInterfaceControlIs094, .controlIs = pgInterfaceControlIs094,
.control = pgInterfaceControl094, .control = pgInterfaceControl094,
.controlVersion = pgInterfaceControlVersion094, .controlVersion = pgInterfaceControlVersion094,
@ -211,6 +208,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal094, .wal = pgInterfaceWal094,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201409291,
.controlTest = pgInterfaceControlTest094, .controlTest = pgInterfaceControlTest094,
.walTest = pgInterfaceWalTest094, .walTest = pgInterfaceWalTest094,
#endif #endif
@ -218,8 +217,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_93, .version = PG_VERSION_93,
.catalogVersion = pgInterfaceCatalogVersion093,
.controlIs = pgInterfaceControlIs093, .controlIs = pgInterfaceControlIs093,
.control = pgInterfaceControl093, .control = pgInterfaceControl093,
.controlVersion = pgInterfaceControlVersion093, .controlVersion = pgInterfaceControlVersion093,
@ -228,6 +225,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal093, .wal = pgInterfaceWal093,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201306121,
.controlTest = pgInterfaceControlTest093, .controlTest = pgInterfaceControlTest093,
.walTest = pgInterfaceWalTest093, .walTest = pgInterfaceWalTest093,
#endif #endif
@ -235,8 +234,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_92, .version = PG_VERSION_92,
.catalogVersion = pgInterfaceCatalogVersion092,
.controlIs = pgInterfaceControlIs092, .controlIs = pgInterfaceControlIs092,
.control = pgInterfaceControl092, .control = pgInterfaceControl092,
.controlVersion = pgInterfaceControlVersion092, .controlVersion = pgInterfaceControlVersion092,
@ -245,6 +242,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal092, .wal = pgInterfaceWal092,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201204301,
.controlTest = pgInterfaceControlTest092, .controlTest = pgInterfaceControlTest092,
.walTest = pgInterfaceWalTest092, .walTest = pgInterfaceWalTest092,
#endif #endif
@ -252,8 +251,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_91, .version = PG_VERSION_91,
.catalogVersion = pgInterfaceCatalogVersion091,
.controlIs = pgInterfaceControlIs091, .controlIs = pgInterfaceControlIs091,
.control = pgInterfaceControl091, .control = pgInterfaceControl091,
.controlVersion = pgInterfaceControlVersion091, .controlVersion = pgInterfaceControlVersion091,
@ -262,6 +259,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal091, .wal = pgInterfaceWal091,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201105231,
.controlTest = pgInterfaceControlTest091, .controlTest = pgInterfaceControlTest091,
.walTest = pgInterfaceWalTest091, .walTest = pgInterfaceWalTest091,
#endif #endif
@ -269,8 +268,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_90, .version = PG_VERSION_90,
.catalogVersion = pgInterfaceCatalogVersion090,
.controlIs = pgInterfaceControlIs090, .controlIs = pgInterfaceControlIs090,
.control = pgInterfaceControl090, .control = pgInterfaceControl090,
.controlVersion = pgInterfaceControlVersion090, .controlVersion = pgInterfaceControlVersion090,
@ -279,6 +276,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal090, .wal = pgInterfaceWal090,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 201008051,
.controlTest = pgInterfaceControlTest090, .controlTest = pgInterfaceControlTest090,
.walTest = pgInterfaceWalTest090, .walTest = pgInterfaceWalTest090,
#endif #endif
@ -286,8 +285,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_84, .version = PG_VERSION_84,
.catalogVersion = pgInterfaceCatalogVersion084,
.controlIs = pgInterfaceControlIs084, .controlIs = pgInterfaceControlIs084,
.control = pgInterfaceControl084, .control = pgInterfaceControl084,
.controlVersion = pgInterfaceControlVersion084, .controlVersion = pgInterfaceControlVersion084,
@ -296,6 +293,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal084, .wal = pgInterfaceWal084,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 200904091,
.controlTest = pgInterfaceControlTest084, .controlTest = pgInterfaceControlTest084,
.walTest = pgInterfaceWalTest084, .walTest = pgInterfaceWalTest084,
#endif #endif
@ -303,8 +302,6 @@ static const PgInterface pgInterface[] =
{ {
.version = PG_VERSION_83, .version = PG_VERSION_83,
.catalogVersion = pgInterfaceCatalogVersion083,
.controlIs = pgInterfaceControlIs083, .controlIs = pgInterfaceControlIs083,
.control = pgInterfaceControl083, .control = pgInterfaceControl083,
.controlVersion = pgInterfaceControlVersion083, .controlVersion = pgInterfaceControlVersion083,
@ -313,6 +310,8 @@ static const PgInterface pgInterface[] =
.wal = pgInterfaceWal083, .wal = pgInterfaceWal083,
#ifdef DEBUG #ifdef DEBUG
.catalogVersion = 200711281,
.controlTest = pgInterfaceControlTest083, .controlTest = pgInterfaceControlTest083,
.walTest = pgInterfaceWalTest083, .walTest = pgInterfaceWalTest083,
#endif #endif
@ -361,17 +360,6 @@ pgInterfaceVersion(unsigned int pgVersion)
FUNCTION_TEST_RETURN(result); FUNCTION_TEST_RETURN(result);
} }
/**********************************************************************************************************************************/
uint32_t
pgCatalogVersion(unsigned int pgVersion)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, pgVersion);
FUNCTION_TEST_END();
FUNCTION_TEST_RETURN(pgInterfaceVersion(pgVersion)->catalogVersion());
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Check expected WAL segment size for older PostgreSQL versions Check expected WAL segment size for older PostgreSQL versions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -559,10 +547,11 @@ pgWalFromFile(const String *walFile, const Storage *storage)
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
String * String *
pgTablespaceId(unsigned int pgVersion) pgTablespaceId(unsigned int pgVersion, unsigned int pgCatalogVersion)
{ {
FUNCTION_TEST_BEGIN(); FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, pgVersion); FUNCTION_TEST_PARAM(UINT, pgVersion);
FUNCTION_TEST_PARAM(UINT, pgCatalogVersion);
FUNCTION_TEST_END(); FUNCTION_TEST_END();
String *result = NULL; String *result = NULL;
@ -575,7 +564,7 @@ pgTablespaceId(unsigned int pgVersion)
MEM_CONTEXT_PRIOR_BEGIN() MEM_CONTEXT_PRIOR_BEGIN()
{ {
result = strNewFmt("PG_%s_%u", strZ(pgVersionStr), pgCatalogVersion(pgVersion)); result = strNewFmt("PG_%s_%u", strZ(pgVersionStr), pgCatalogVersion);
} }
MEM_CONTEXT_PRIOR_END(); MEM_CONTEXT_PRIOR_END();
} }
@ -758,6 +747,21 @@ pgXactPath(unsigned int pgVersion)
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
#ifdef DEBUG #ifdef DEBUG
unsigned int
pgCatalogTestVersion(unsigned int pgVersion)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, pgVersion);
FUNCTION_TEST_END();
FUNCTION_TEST_RETURN(pgInterfaceVersion(pgVersion)->catalogVersion);
}
#endif
/**********************************************************************************************************************************/
#ifdef DEBUG
Buffer * Buffer *
pgControlTestToBuffer(PgControl pgControl) pgControlTestToBuffer(PgControl pgControl)
{ {
@ -768,6 +772,8 @@ pgControlTestToBuffer(PgControl pgControl)
// Set defaults if values are not passed // Set defaults if values are not passed
pgControl.pageSize = pgControl.pageSize == 0 ? PG_PAGE_SIZE_DEFAULT : pgControl.pageSize; pgControl.pageSize = pgControl.pageSize == 0 ? PG_PAGE_SIZE_DEFAULT : pgControl.pageSize;
pgControl.walSegmentSize = pgControl.walSegmentSize == 0 ? PG_WAL_SEGMENT_SIZE_DEFAULT : pgControl.walSegmentSize; pgControl.walSegmentSize = pgControl.walSegmentSize == 0 ? PG_WAL_SEGMENT_SIZE_DEFAULT : pgControl.walSegmentSize;
pgControl.catalogVersion = pgControl.catalogVersion == 0 ?
pgInterfaceVersion(pgControl.version)->catalogVersion : pgControl.catalogVersion;
// Create the buffer and clear it // Create the buffer and clear it
Buffer *result = bufNew(PG_CONTROL_SIZE); Buffer *result = bufNew(PG_CONTROL_SIZE);

View File

@ -109,6 +109,7 @@ typedef struct PgControl
{ {
unsigned int version; unsigned int version;
uint64_t systemId; uint64_t systemId;
unsigned int catalogVersion;
unsigned int pageSize; unsigned int pageSize;
unsigned int walSegmentSize; unsigned int walSegmentSize;
@ -129,9 +130,6 @@ typedef struct PgWal
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Functions Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
// Get the catalog version for a PostgreSQL version
uint32_t pgCatalogVersion(unsigned int pgVersion);
// Get info from pg_control // Get info from pg_control
PgControl pgControlFromFile(const Storage *storage); PgControl pgControlFromFile(const Storage *storage);
PgControl pgControlFromBuffer(const Buffer *controlFile); PgControl pgControlFromBuffer(const Buffer *controlFile);
@ -148,7 +146,7 @@ PgWal pgWalFromFile(const String *walFile, const Storage *storage);
PgWal pgWalFromBuffer(const Buffer *walBuffer); PgWal pgWalFromBuffer(const Buffer *walBuffer);
// Get the tablespace identifier used to distinguish versions in a tablespace directory, e.g. PG_9.0_201008051 // Get the tablespace identifier used to distinguish versions in a tablespace directory, e.g. PG_9.0_201008051
String *pgTablespaceId(unsigned int pgVersion); String *pgTablespaceId(unsigned int pgVersion, unsigned int pgCatalogVersion);
// Convert a string to an lsn and vice versa // Convert a string to an lsn and vice versa
uint64_t pgLsnFromStr(const String *lsn); uint64_t pgLsnFromStr(const String *lsn);
@ -180,6 +178,9 @@ const String *pgXactPath(unsigned int pgVersion);
Test Functions Test Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#ifdef DEBUG #ifdef DEBUG
// Get the catalog version for a PostgreSQL version for testing
unsigned int pgCatalogTestVersion(unsigned int pgVersion);
// Create pg_control for testing // Create pg_control for testing
Buffer *pgControlTestToBuffer(PgControl pgControl); Buffer *pgControlTestToBuffer(PgControl pgControl);

View File

@ -9,91 +9,78 @@ PostgreSQL Version Interface
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Functions Functions
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
uint32_t pgInterfaceCatalogVersion083(void);
bool pgInterfaceControlIs083(const unsigned char *controlFile); bool pgInterfaceControlIs083(const unsigned char *controlFile);
PgControl pgInterfaceControl083(const unsigned char *controlFile); PgControl pgInterfaceControl083(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion083(void); uint32_t pgInterfaceControlVersion083(void);
bool pgInterfaceWalIs083(const unsigned char *walFile); bool pgInterfaceWalIs083(const unsigned char *walFile);
PgWal pgInterfaceWal083(const unsigned char *controlFile); PgWal pgInterfaceWal083(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion084(void);
bool pgInterfaceControlIs084(const unsigned char *controlFile); bool pgInterfaceControlIs084(const unsigned char *controlFile);
PgControl pgInterfaceControl084(const unsigned char *controlFile); PgControl pgInterfaceControl084(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion084(void); uint32_t pgInterfaceControlVersion084(void);
bool pgInterfaceWalIs084(const unsigned char *walFile); bool pgInterfaceWalIs084(const unsigned char *walFile);
PgWal pgInterfaceWal084(const unsigned char *controlFile); PgWal pgInterfaceWal084(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion090(void);
bool pgInterfaceControlIs090(const unsigned char *controlFile); bool pgInterfaceControlIs090(const unsigned char *controlFile);
PgControl pgInterfaceControl090(const unsigned char *controlFile); PgControl pgInterfaceControl090(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion090(void); uint32_t pgInterfaceControlVersion090(void);
bool pgInterfaceWalIs090(const unsigned char *walFile); bool pgInterfaceWalIs090(const unsigned char *walFile);
PgWal pgInterfaceWal090(const unsigned char *controlFile); PgWal pgInterfaceWal090(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion091(void);
bool pgInterfaceControlIs091(const unsigned char *controlFile); bool pgInterfaceControlIs091(const unsigned char *controlFile);
PgControl pgInterfaceControl091(const unsigned char *controlFile); PgControl pgInterfaceControl091(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion091(void); uint32_t pgInterfaceControlVersion091(void);
bool pgInterfaceWalIs091(const unsigned char *walFile); bool pgInterfaceWalIs091(const unsigned char *walFile);
PgWal pgInterfaceWal091(const unsigned char *controlFile); PgWal pgInterfaceWal091(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion092(void);
bool pgInterfaceControlIs092(const unsigned char *controlFile); bool pgInterfaceControlIs092(const unsigned char *controlFile);
PgControl pgInterfaceControl092(const unsigned char *controlFile); PgControl pgInterfaceControl092(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion092(void); uint32_t pgInterfaceControlVersion092(void);
bool pgInterfaceWalIs092(const unsigned char *walFile); bool pgInterfaceWalIs092(const unsigned char *walFile);
PgWal pgInterfaceWal092(const unsigned char *controlFile); PgWal pgInterfaceWal092(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion093(void);
bool pgInterfaceControlIs093(const unsigned char *controlFile); bool pgInterfaceControlIs093(const unsigned char *controlFile);
PgControl pgInterfaceControl093(const unsigned char *controlFile); PgControl pgInterfaceControl093(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion093(void); uint32_t pgInterfaceControlVersion093(void);
bool pgInterfaceWalIs093(const unsigned char *walFile); bool pgInterfaceWalIs093(const unsigned char *walFile);
PgWal pgInterfaceWal093(const unsigned char *controlFile); PgWal pgInterfaceWal093(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion094(void);
bool pgInterfaceControlIs094(const unsigned char *controlFile); bool pgInterfaceControlIs094(const unsigned char *controlFile);
PgControl pgInterfaceControl094(const unsigned char *controlFile); PgControl pgInterfaceControl094(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion094(void); uint32_t pgInterfaceControlVersion094(void);
bool pgInterfaceWalIs094(const unsigned char *walFile); bool pgInterfaceWalIs094(const unsigned char *walFile);
PgWal pgInterfaceWal094(const unsigned char *controlFile); PgWal pgInterfaceWal094(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion095(void);
bool pgInterfaceControlIs095(const unsigned char *controlFile); bool pgInterfaceControlIs095(const unsigned char *controlFile);
PgControl pgInterfaceControl095(const unsigned char *controlFile); PgControl pgInterfaceControl095(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion095(void); uint32_t pgInterfaceControlVersion095(void);
bool pgInterfaceWalIs095(const unsigned char *walFile); bool pgInterfaceWalIs095(const unsigned char *walFile);
PgWal pgInterfaceWal095(const unsigned char *controlFile); PgWal pgInterfaceWal095(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion096(void);
bool pgInterfaceControlIs096(const unsigned char *controlFile); bool pgInterfaceControlIs096(const unsigned char *controlFile);
PgControl pgInterfaceControl096(const unsigned char *controlFile); PgControl pgInterfaceControl096(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion096(void); uint32_t pgInterfaceControlVersion096(void);
bool pgInterfaceWalIs096(const unsigned char *walFile); bool pgInterfaceWalIs096(const unsigned char *walFile);
PgWal pgInterfaceWal096(const unsigned char *controlFile); PgWal pgInterfaceWal096(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion100(void);
bool pgInterfaceControlIs100(const unsigned char *controlFile); bool pgInterfaceControlIs100(const unsigned char *controlFile);
PgControl pgInterfaceControl100(const unsigned char *controlFile); PgControl pgInterfaceControl100(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion100(void); uint32_t pgInterfaceControlVersion100(void);
bool pgInterfaceWalIs100(const unsigned char *walFile); bool pgInterfaceWalIs100(const unsigned char *walFile);
PgWal pgInterfaceWal100(const unsigned char *controlFile); PgWal pgInterfaceWal100(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion110(void);
bool pgInterfaceControlIs110(const unsigned char *controlFile); bool pgInterfaceControlIs110(const unsigned char *controlFile);
PgControl pgInterfaceControl110(const unsigned char *controlFile); PgControl pgInterfaceControl110(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion110(void); uint32_t pgInterfaceControlVersion110(void);
bool pgInterfaceWalIs110(const unsigned char *walFile); bool pgInterfaceWalIs110(const unsigned char *walFile);
PgWal pgInterfaceWal110(const unsigned char *controlFile); PgWal pgInterfaceWal110(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion120(void);
bool pgInterfaceControlIs120(const unsigned char *controlFile); bool pgInterfaceControlIs120(const unsigned char *controlFile);
PgControl pgInterfaceControl120(const unsigned char *controlFile); PgControl pgInterfaceControl120(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion120(void); uint32_t pgInterfaceControlVersion120(void);
bool pgInterfaceWalIs120(const unsigned char *walFile); bool pgInterfaceWalIs120(const unsigned char *walFile);
PgWal pgInterfaceWal120(const unsigned char *controlFile); PgWal pgInterfaceWal120(const unsigned char *controlFile);
uint32_t pgInterfaceCatalogVersion130(void);
bool pgInterfaceControlIs130(const unsigned char *controlFile); bool pgInterfaceControlIs130(const unsigned char *controlFile);
PgControl pgInterfaceControl130(const unsigned char *controlFile); PgControl pgInterfaceControl130(const unsigned char *controlFile);
uint32_t pgInterfaceControlVersion130(void); uint32_t pgInterfaceControlVersion130(void);

View File

@ -17,22 +17,6 @@ Each version of PostgreSQL will need a vXXX.c file to contain the version-specif
#include "postgres/interface/version.vendor.h" #include "postgres/interface/version.vendor.h"
/***********************************************************************************************************************************
Get the catalog version
***********************************************************************************************************************************/
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#define PG_INTERFACE_CATALOG_VERSION(version) \
uint32_t \
pgInterfaceCatalogVersion##version(void) \
{ \
return CATALOG_VERSION_NO; \
}
#endif
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Determine if the supplied pg_control is for this version of PostgreSQL Determine if the supplied pg_control is for this version of PostgreSQL
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@ -40,6 +24,8 @@ Determine if the supplied pg_control is for this version of PostgreSQL
#elif PG_VERSION >= PG_VERSION_83 #elif PG_VERSION >= PG_VERSION_83
#ifdef CATALOG_VERSION_NO
#define PG_INTERFACE_CONTROL_IS(version) \ #define PG_INTERFACE_CONTROL_IS(version) \
bool \ bool \
pgInterfaceControlIs##version(const unsigned char *controlFile) \ pgInterfaceControlIs##version(const unsigned char *controlFile) \
@ -51,6 +37,19 @@ Determine if the supplied pg_control is for this version of PostgreSQL
((ControlFileData *)controlFile)->catalog_version_no == CATALOG_VERSION_NO; \ ((ControlFileData *)controlFile)->catalog_version_no == CATALOG_VERSION_NO; \
} }
#else
#define PG_INTERFACE_CONTROL_IS(version) \
bool \
pgInterfaceControlIs##version(const unsigned char *controlFile) \
{ \
ASSERT(controlFile != NULL); \
\
return ((ControlFileData *)controlFile)->pg_control_version == PG_CONTROL_VERSION; \
}
#endif // CATALOG_VERSION_NO
#endif #endif
/*********************************************************************************************************************************** /***********************************************************************************************************************************
@ -70,6 +69,7 @@ Read the version specific pg_control into a general data structure
return (PgControl) \ return (PgControl) \
{ \ { \
.systemId = ((ControlFileData *)controlFile)->system_identifier, \ .systemId = ((ControlFileData *)controlFile)->system_identifier, \
.catalogVersion = ((ControlFileData *)controlFile)->catalog_version_no, \
.pageSize = ((ControlFileData *)controlFile)->blcksz, \ .pageSize = ((ControlFileData *)controlFile)->blcksz, \
.walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \ .walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \
.pageChecksum = ((ControlFileData *)controlFile)->data_checksum_version != 0, \ .pageChecksum = ((ControlFileData *)controlFile)->data_checksum_version != 0, \
@ -88,6 +88,7 @@ Read the version specific pg_control into a general data structure
return (PgControl) \ return (PgControl) \
{ \ { \
.systemId = ((ControlFileData *)controlFile)->system_identifier, \ .systemId = ((ControlFileData *)controlFile)->system_identifier, \
.catalogVersion = ((ControlFileData *)controlFile)->catalog_version_no, \
.pageSize = ((ControlFileData *)controlFile)->blcksz, \ .pageSize = ((ControlFileData *)controlFile)->blcksz, \
.walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \ .walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \
}; \ }; \
@ -128,7 +129,7 @@ Create a pg_control file for testing
{ \ { \
.system_identifier = pgControl.systemId, \ .system_identifier = pgControl.systemId, \
.pg_control_version = PG_CONTROL_VERSION, \ .pg_control_version = PG_CONTROL_VERSION, \
.catalog_version_no = CATALOG_VERSION_NO, \ .catalog_version_no = pgControl.catalogVersion, \
.blcksz = pgControl.pageSize, \ .blcksz = pgControl.pageSize, \
.xlog_seg_size = pgControl.walSegmentSize, \ .xlog_seg_size = pgControl.walSegmentSize, \
.data_checksum_version = pgControl.pageChecksum, \ .data_checksum_version = pgControl.pageChecksum, \
@ -148,7 +149,7 @@ Create a pg_control file for testing
{ \ { \
.system_identifier = pgControl.systemId, \ .system_identifier = pgControl.systemId, \
.pg_control_version = PG_CONTROL_VERSION, \ .pg_control_version = PG_CONTROL_VERSION, \
.catalog_version_no = CATALOG_VERSION_NO, \ .catalog_version_no = pgControl.catalogVersion, \
.blcksz = pgControl.pageSize, \ .blcksz = pgControl.pageSize, \
.xlog_seg_size = pgControl.walSegmentSize, \ .xlog_seg_size = pgControl.walSegmentSize, \
}; \ }; \
@ -220,7 +221,6 @@ Create a WAL file file for testing
Call all macros with a single macro to make the vXXX.c files as simple as possible Call all macros with a single macro to make the vXXX.c files as simple as possible
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
#define PG_INTERFACE_BASE(version) \ #define PG_INTERFACE_BASE(version) \
PG_INTERFACE_CATALOG_VERSION(version) \
PG_INTERFACE_CONTROL_IS(version) \ PG_INTERFACE_CONTROL_IS(version) \
PG_INTERFACE_CONTROL(version) \ PG_INTERFACE_CONTROL(version) \
PG_INTERFACE_CONTROL_VERSION(version) \ PG_INTERFACE_CONTROL_VERSION(version) \

View File

@ -177,71 +177,17 @@ Types from src/include/catalog/catversion.h
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
// CATALOG_VERSION_NO define // CATALOG_VERSION_NO define
//
// Add CATALOG_VERSION_NO when more than one PostgreSQL version shares a control version so the PostgreSQL version can be reliably
// identified. Newer versions of PostgreSQL have bumped the control version but that has not always been the case.
//
// Undef CATALOG_VERSION_NO in PostgreSQL versions where it is not required to improve readability.
// --------------------------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------------------------------
#if PG_VERSION > PG_VERSION_MAX #if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_13
/*
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202007201
#elif PG_VERSION >= PG_VERSION_12
/*
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201909212
#elif PG_VERSION >= PG_VERSION_11
/*
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201809051
#elif PG_VERSION >= PG_VERSION_10
/*
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201707211
#elif PG_VERSION >= PG_VERSION_96 #elif PG_VERSION >= PG_VERSION_96
/* #undef CATALOG_VERSION_NO
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201608131
#elif PG_VERSION >= PG_VERSION_95 #elif PG_VERSION >= PG_VERSION_95
@ -269,31 +215,9 @@ Types from src/include/catalog/catversion.h
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201409291 #define CATALOG_VERSION_NO 201409291
#elif PG_VERSION >= PG_VERSION_93
/*
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201306121
#elif PG_VERSION >= PG_VERSION_92 #elif PG_VERSION >= PG_VERSION_92
/* #undef CATALOG_VERSION_NO
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201204301
#elif PG_VERSION >= PG_VERSION_91 #elif PG_VERSION >= PG_VERSION_91
@ -321,31 +245,9 @@ Types from src/include/catalog/catversion.h
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201008051 #define CATALOG_VERSION_NO 201008051
#elif PG_VERSION >= PG_VERSION_84
/*
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200904091
#elif PG_VERSION >= PG_VERSION_83 #elif PG_VERSION >= PG_VERSION_83
/* #undef CATALOG_VERSION_NO
* We could use anything we wanted for version numbers, but I recommend
* following the "YYYYMMDDN" style often used for DNS zone serial numbers.
* YYYYMMDD are the date of the change, and N is the number of the change
* on that day. (Hopefully we'll never commit ten independent sets of
* catalog changes on the same day...)
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200711281
#endif #endif

View File

@ -1016,7 +1016,7 @@ testRun(void)
harnessCfgLoad(cfgCmdBackup, argList); harnessCfgLoad(cfgCmdBackup, argList);
TEST_ERROR( TEST_ERROR(
backupInit(infoBackupNew(PG_VERSION_91, 1000000000000000910, NULL)), ConfigError, backupInit(infoBackupNew(PG_VERSION_91, 1000000000000000910, pgCatalogTestVersion(PG_VERSION_91), NULL)), ConfigError,
"option 'backup-standby' not valid for PostgreSQL < 9.2"); "option 'backup-standby' not valid for PostgreSQL < 9.2");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
@ -1036,7 +1036,9 @@ testRun(void)
strLstAddZ(argList, "--no-" CFGOPT_ONLINE); strLstAddZ(argList, "--no-" CFGOPT_ONLINE);
harnessCfgLoad(cfgCmdBackup, argList); harnessCfgLoad(cfgCmdBackup, argList);
TEST_RESULT_VOID(backupInit(infoBackupNew(PG_VERSION_92, 1000000000000000920, NULL)), "backup init"); TEST_RESULT_VOID(
backupInit(infoBackupNew(PG_VERSION_92, 1000000000000000920, pgCatalogTestVersion(PG_VERSION_92), NULL)),
"backup init");
TEST_RESULT_BOOL(cfgOptionBool(cfgOptBackupStandby), false, " check backup-standby"); TEST_RESULT_BOOL(cfgOptionBool(cfgOptBackupStandby), false, " check backup-standby");
TEST_RESULT_LOG( TEST_RESULT_LOG(
@ -1059,11 +1061,13 @@ testRun(void)
harnessCfgLoad(cfgCmdBackup, argList); harnessCfgLoad(cfgCmdBackup, argList);
TEST_ERROR( TEST_ERROR(
backupInit(infoBackupNew(PG_VERSION_11, 1000000000000001100, NULL)), BackupMismatchError, backupInit(infoBackupNew(PG_VERSION_11, 1000000000000001100, pgCatalogTestVersion(PG_VERSION_11), NULL)),
BackupMismatchError,
"PostgreSQL version 10, system-id 1000000000000001000 do not match stanza version 11, system-id 1000000000000001100\n" "PostgreSQL version 10, system-id 1000000000000001000 do not match stanza version 11, system-id 1000000000000001100\n"
"HINT: is this the correct stanza?"); "HINT: is this the correct stanza?");
TEST_ERROR( TEST_ERROR(
backupInit(infoBackupNew(PG_VERSION_10, 1000000000000001100, NULL)), BackupMismatchError, backupInit(infoBackupNew(PG_VERSION_10, 1000000000000001100, pgCatalogTestVersion(PG_VERSION_10), NULL)),
BackupMismatchError,
"PostgreSQL version 10, system-id 1000000000000001000 do not match stanza version 10, system-id 1000000000000001100\n" "PostgreSQL version 10, system-id 1000000000000001000 do not match stanza version 10, system-id 1000000000000001100\n"
"HINT: is this the correct stanza?"); "HINT: is this the correct stanza?");
@ -1084,7 +1088,9 @@ testRun(void)
strLstAddZ(argList, "--" CFGOPT_START_FAST); strLstAddZ(argList, "--" CFGOPT_START_FAST);
harnessCfgLoad(cfgCmdBackup, argList); harnessCfgLoad(cfgCmdBackup, argList);
TEST_RESULT_VOID(backupInit(infoBackupNew(PG_VERSION_83, 1000000000000000830, NULL)), "backup init"); TEST_RESULT_VOID(
backupInit(infoBackupNew(PG_VERSION_83, 1000000000000000830, pgCatalogTestVersion(PG_VERSION_83), NULL)),
"backup init");
TEST_RESULT_BOOL(cfgOptionBool(cfgOptStartFast), false, " check start-fast"); TEST_RESULT_BOOL(cfgOptionBool(cfgOptStartFast), false, " check start-fast");
TEST_RESULT_LOG("P00 WARN: start-fast option is only available in PostgreSQL >= 8.4"); TEST_RESULT_LOG("P00 WARN: start-fast option is only available in PostgreSQL >= 8.4");
@ -1106,7 +1112,9 @@ testRun(void)
strLstAddZ(argList, "--" CFGOPT_STOP_AUTO); strLstAddZ(argList, "--" CFGOPT_STOP_AUTO);
harnessCfgLoad(cfgCmdBackup, argList); harnessCfgLoad(cfgCmdBackup, argList);
TEST_RESULT_VOID(backupInit(infoBackupNew(PG_VERSION_84, 1000000000000000840, NULL)), "backup init"); TEST_RESULT_VOID(
backupInit(infoBackupNew(PG_VERSION_84, 1000000000000000840, pgCatalogTestVersion(PG_VERSION_84), NULL)),
"backup init");
TEST_RESULT_BOOL(cfgOptionBool(cfgOptStopAuto), false, " check stop-auto"); TEST_RESULT_BOOL(cfgOptionBool(cfgOptStopAuto), false, " check stop-auto");
TEST_RESULT_LOG("P00 WARN: stop-auto option is only available in PostgreSQL >= 9.3"); TEST_RESULT_LOG("P00 WARN: stop-auto option is only available in PostgreSQL >= 9.3");
@ -1135,7 +1143,9 @@ testRun(void)
HRNPQ_MACRO_DONE() HRNPQ_MACRO_DONE()
}); });
TEST_RESULT_VOID(dbFree(backupInit(infoBackupNew(PG_VERSION_93, PG_VERSION_93, NULL))->dbPrimary), "backup init"); TEST_RESULT_VOID(
dbFree(backupInit(infoBackupNew(PG_VERSION_93, PG_VERSION_93, pgCatalogTestVersion(PG_VERSION_93), NULL))->dbPrimary),
"backup init");
TEST_RESULT_BOOL(cfgOptionBool(cfgOptChecksumPage), false, " check checksum-page"); TEST_RESULT_BOOL(cfgOptionBool(cfgOptChecksumPage), false, " check checksum-page");
TEST_RESULT_LOG( TEST_RESULT_LOG(
@ -1165,7 +1175,9 @@ testRun(void)
HRNPQ_MACRO_DONE() HRNPQ_MACRO_DONE()
}); });
TEST_RESULT_VOID(dbFree(backupInit(infoBackupNew(PG_VERSION_93, PG_VERSION_93, NULL))->dbPrimary), "backup init"); TEST_RESULT_VOID(
dbFree(backupInit(infoBackupNew(PG_VERSION_93, PG_VERSION_93, pgCatalogTestVersion(PG_VERSION_93), NULL))->dbPrimary),
"backup init");
TEST_RESULT_BOOL(cfgOptionBool(cfgOptChecksumPage), false, " check checksum-page"); TEST_RESULT_BOOL(cfgOptionBool(cfgOptChecksumPage), false, " check checksum-page");
// Create pg_control without page checksums // Create pg_control without page checksums
@ -1181,7 +1193,9 @@ testRun(void)
HRNPQ_MACRO_DONE() HRNPQ_MACRO_DONE()
}); });
TEST_RESULT_VOID(dbFree(backupInit(infoBackupNew(PG_VERSION_93, PG_VERSION_93, NULL))->dbPrimary), "backup init"); TEST_RESULT_VOID(
dbFree(backupInit(infoBackupNew(PG_VERSION_93, PG_VERSION_93, pgCatalogTestVersion(PG_VERSION_93), NULL))->dbPrimary),
"backup init");
TEST_RESULT_BOOL(cfgOptionBool(cfgOptChecksumPage), false, " check checksum-page"); TEST_RESULT_BOOL(cfgOptionBool(cfgOptChecksumPage), false, " check checksum-page");
} }
@ -1218,7 +1232,8 @@ testRun(void)
HRNPQ_MACRO_DONE() HRNPQ_MACRO_DONE()
}); });
BackupData *backupData = backupInit(infoBackupNew(PG_VERSION_93, PG_VERSION_93, NULL)); BackupData *backupData = backupInit(
infoBackupNew(PG_VERSION_93, PG_VERSION_93, pgCatalogTestVersion(PG_VERSION_93), NULL));
TEST_ERROR(backupTime(backupData, true), AssertError, "invalid sleep for online backup time with wait remainder"); TEST_ERROR(backupTime(backupData, true), AssertError, "invalid sleep for online backup time with wait remainder");
dbFree(backupData->dbPrimary); dbFree(backupData->dbPrimary);
@ -1634,7 +1649,8 @@ testRun(void)
storagePathCreateP(storagePgWrite(), pgWalPath(PG_VERSION_95), .noParentCreate = true); storagePathCreateP(storagePgWrite(), pgWalPath(PG_VERSION_95), .noParentCreate = true);
// Create a backup manifest that looks like a halted backup manifest // Create a backup manifest that looks like a halted backup manifest
Manifest *manifestResume = manifestNewBuild(storagePg(), PG_VERSION_95, true, false, NULL, NULL); Manifest *manifestResume = manifestNewBuild(
storagePg(), PG_VERSION_95, pgCatalogTestVersion(PG_VERSION_95), true, false, NULL, NULL);
ManifestData *manifestResumeData = (ManifestData *)manifestData(manifestResume); ManifestData *manifestResumeData = (ManifestData *)manifestData(manifestResume);
manifestResumeData->backupType = backupTypeFull; manifestResumeData->backupType = backupTypeFull;
@ -1721,7 +1737,8 @@ testRun(void)
harnessCfgLoad(cfgCmdBackup, argList); harnessCfgLoad(cfgCmdBackup, argList);
// Create a backup manifest that looks like a halted backup manifest // Create a backup manifest that looks like a halted backup manifest
Manifest *manifestResume = manifestNewBuild(storagePg(), PG_VERSION_95, true, false, NULL, NULL); Manifest *manifestResume = manifestNewBuild(
storagePg(), PG_VERSION_95, pgCatalogTestVersion(PG_VERSION_95), true, false, NULL, NULL);
ManifestData *manifestResumeData = (ManifestData *)manifestData(manifestResume); ManifestData *manifestResumeData = (ManifestData *)manifestData(manifestResume);
manifestResumeData->backupType = backupTypeFull; manifestResumeData->backupType = backupTypeFull;
@ -1914,7 +1931,8 @@ testRun(void)
manifestSave(manifestPrior, storageWriteIo(storageNewWriteP(storageRepoWrite(), manifestPriorFile))); manifestSave(manifestPrior, storageWriteIo(storageNewWriteP(storageRepoWrite(), manifestPriorFile)));
// Create a backup manifest that looks like a halted backup manifest // Create a backup manifest that looks like a halted backup manifest
Manifest *manifestResume = manifestNewBuild(storagePg(), PG_VERSION_95, true, false, NULL, NULL); Manifest *manifestResume = manifestNewBuild(
storagePg(), PG_VERSION_95, pgCatalogTestVersion(PG_VERSION_95), true, false, NULL, NULL);
ManifestData *manifestResumeData = (ManifestData *)manifestData(manifestResume); ManifestData *manifestResumeData = (ManifestData *)manifestData(manifestResume);
manifestResumeData->backupType = backupTypeDiff; manifestResumeData->backupType = backupTypeDiff;
@ -2287,7 +2305,8 @@ testRun(void)
storagePutP( storagePutP(
storageNewWriteP( storageNewWriteP(
storageTest, strNewFmt("pg1-tblspc/32768/%s/1/5", strZ(pgTablespaceId(PG_VERSION_11))), storageTest,
strNewFmt("pg1-tblspc/32768/%s/1/5", strZ(pgTablespaceId(PG_VERSION_11, pgCatalogTestVersion(PG_VERSION_11)))),
.timeModified = backupTimeStart), .timeModified = backupTimeStart),
NULL); NULL);

View File

@ -444,14 +444,14 @@ testRun(void)
InfoArchive *archiveInfo = infoArchiveNew(PG_VERSION_96, 6569239123849665679, NULL); InfoArchive *archiveInfo = infoArchiveNew(PG_VERSION_96, 6569239123849665679, NULL);
InfoPgData archivePg = infoPgData(infoArchivePg(archiveInfo), infoPgDataCurrentId(infoArchivePg(archiveInfo))); InfoPgData archivePg = infoPgData(infoArchivePg(archiveInfo), infoPgDataCurrentId(infoArchivePg(archiveInfo)));
InfoBackup *backupInfo = infoBackupNew(PG_VERSION_96, 6569239123849665679, NULL); InfoBackup *backupInfo = infoBackupNew(PG_VERSION_96, 6569239123849665679, pgCatalogTestVersion(PG_VERSION_96), NULL);
InfoPgData backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo))); InfoPgData backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
TEST_RESULT_VOID(checkStanzaInfo(&archivePg, &backupPg), "stanza info files match"); TEST_RESULT_VOID(checkStanzaInfo(&archivePg, &backupPg), "stanza info files match");
// Create a corrupted backup file - system id // Create a corrupted backup file - system id
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
backupInfo = infoBackupNew(PG_VERSION_96, 6569239123849665999, NULL); backupInfo = infoBackupNew(PG_VERSION_96, 6569239123849665999, pgCatalogTestVersion(PG_VERSION_96), NULL);
backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo))); backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
TEST_ERROR_FMT( TEST_ERROR_FMT(
@ -462,7 +462,7 @@ testRun(void)
// Create a corrupted backup file - system id and version // Create a corrupted backup file - system id and version
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
backupInfo = infoBackupNew(PG_VERSION_95, 6569239123849665999, NULL); backupInfo = infoBackupNew(PG_VERSION_95, 6569239123849665999, pgCatalogTestVersion(PG_VERSION_95), NULL);
backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo))); backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
TEST_ERROR_FMT( TEST_ERROR_FMT(
@ -473,7 +473,7 @@ testRun(void)
// Create a corrupted backup file - version // Create a corrupted backup file - version
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
backupInfo = infoBackupNew(PG_VERSION_95, 6569239123849665679, NULL); backupInfo = infoBackupNew(PG_VERSION_95, 6569239123849665679, pgCatalogTestVersion(PG_VERSION_95), NULL);
backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo))); backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
TEST_ERROR_FMT( TEST_ERROR_FMT(
@ -484,7 +484,7 @@ testRun(void)
// Create a corrupted backup file - db id // Create a corrupted backup file - db id
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
infoBackupPgSet(backupInfo, PG_VERSION_96, 6569239123849665679); infoBackupPgSet(backupInfo, PG_VERSION_96, 6569239123849665679, pgCatalogTestVersion(PG_VERSION_96));
backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo))); backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
TEST_ERROR_FMT( TEST_ERROR_FMT(

View File

@ -1279,6 +1279,7 @@ testRun(void)
TEST_TITLE("one database selected with tablespace id"); TEST_TITLE("one database selected with tablespace id");
manifest->data.pgVersion = PG_VERSION_94; manifest->data.pgVersion = PG_VERSION_94;
manifest->data.pgCatalogVersion = pgCatalogTestVersion(PG_VERSION_94);
MEM_CONTEXT_BEGIN(manifest->memContext) MEM_CONTEXT_BEGIN(manifest->memContext)
{ {
@ -2015,6 +2016,7 @@ testRun(void)
manifest->info = infoNew(NULL); manifest->info = infoNew(NULL);
manifest->data.backupLabel = strNew(TEST_LABEL); manifest->data.backupLabel = strNew(TEST_LABEL);
manifest->data.pgVersion = PG_VERSION_10; manifest->data.pgVersion = PG_VERSION_10;
manifest->data.pgCatalogVersion = pgCatalogTestVersion(PG_VERSION_10);
manifest->data.backupType = backupTypeFull; manifest->data.backupType = backupTypeFull;
manifest->data.backupTimestampCopyStart = 1482182861; // So file timestamps should be less than this manifest->data.backupTimestampCopyStart = 1482182861; // So file timestamps should be less than this

View File

@ -479,6 +479,7 @@ testRun(void)
TEST_ASSIGN(pgControl, pgValidate(), "validate primary on pg2"); TEST_ASSIGN(pgControl, pgValidate(), "validate primary on pg2");
TEST_RESULT_UINT(pgControl.version, PG_VERSION_92, " version set"); TEST_RESULT_UINT(pgControl.version, PG_VERSION_92, " version set");
TEST_RESULT_UINT(pgControl.systemId, 6569239123849665699, " systemId set"); TEST_RESULT_UINT(pgControl.systemId, 6569239123849665699, " systemId set");
TEST_RESULT_UINT(pgControl.catalogVersion, 201204301, " catalogVersion set");
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************

View File

@ -59,7 +59,7 @@ testRun(void)
Buffer *contentCompare = bufNew(0); Buffer *contentCompare = bufNew(0);
TEST_ASSIGN( TEST_ASSIGN(
infoBackup, infoBackupNew(PG_VERSION_94, 6569239123849665679, NULL), infoBackup, infoBackupNew(PG_VERSION_94, 6569239123849665679, pgCatalogTestVersion(PG_VERSION_94), NULL),
"infoBackupNew() - no cipher sub"); "infoBackupNew() - no cipher sub");
TEST_RESULT_VOID(infoBackupSave(infoBackup, ioBufferWriteNew(contentCompare)), " save backup info from new"); TEST_RESULT_VOID(infoBackupSave(infoBackup, ioBufferWriteNew(contentCompare)), " save backup info from new");
TEST_RESULT_STR(strNewBuf(contentCompare), strNewBuf(contentSave), " check save"); TEST_RESULT_STR(strNewBuf(contentCompare), strNewBuf(contentSave), " check save");
@ -74,7 +74,8 @@ testRun(void)
TEST_ASSIGN( TEST_ASSIGN(
infoBackup, infoBackup,
infoBackupNew( infoBackupNew(
PG_VERSION_10, 6569239123849665999, strNew("zWa/6Xtp-IVZC5444yXB+cgFDFl7MxGlgkZSaoPvTGirhPygu4jOKOXf9LO4vjfO")), PG_VERSION_10, 6569239123849665999, pgCatalogTestVersion(PG_VERSION_10),
strNew("zWa/6Xtp-IVZC5444yXB+cgFDFl7MxGlgkZSaoPvTGirhPygu4jOKOXf9LO4vjfO")),
"infoBackupNew() - cipher sub"); "infoBackupNew() - cipher sub");
contentSave = bufNew(0); contentSave = bufNew(0);
@ -91,11 +92,14 @@ testRun(void)
// Add pg info // Add pg info
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
InfoPgData infoPgData = {0}; InfoPgData infoPgData = {0};
TEST_RESULT_VOID(infoBackupPgSet(infoBackup, PG_VERSION_94, 6569239123849665679), "add another infoPg"); TEST_RESULT_VOID(
infoBackupPgSet(infoBackup, PG_VERSION_94, 6569239123849665679, pgCatalogTestVersion(PG_VERSION_94)),
"add another infoPg");
TEST_RESULT_INT(infoPgDataTotal(infoBackup->infoPg), 2, " history incremented"); TEST_RESULT_INT(infoPgDataTotal(infoBackup->infoPg), 2, " history incremented");
TEST_ASSIGN(infoPgData, infoPgDataCurrent(infoBackup->infoPg), " get current infoPgData"); TEST_ASSIGN(infoPgData, infoPgDataCurrent(infoBackup->infoPg), " get current infoPgData");
TEST_RESULT_INT(infoPgData.version, PG_VERSION_94, " version set"); TEST_RESULT_INT(infoPgData.version, PG_VERSION_94, " version set");
TEST_RESULT_UINT(infoPgData.systemId, 6569239123849665679, " systemId set"); TEST_RESULT_UINT(infoPgData.systemId, 6569239123849665679, " systemId set");
TEST_RESULT_UINT(infoPgData.catalogVersion, 201409291, " catalogVersion set");
// Free // Free
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
@ -695,7 +699,9 @@ testRun(void)
"20190818-084777F, 20190923-164324F", "confirm backups on disk"); "20190818-084777F, 20190923-164324F", "confirm backups on disk");
// With the infoBackup from above, upgrade the DB so there a 2 histories then save to disk // With the infoBackup from above, upgrade the DB so there a 2 histories then save to disk
TEST_ASSIGN(infoBackup, infoBackupPgSet(infoBackup, PG_VERSION_11, 6739907367085689196), "upgrade db"); TEST_ASSIGN(
infoBackup, infoBackupPgSet(infoBackup, PG_VERSION_11, 6739907367085689196, pgCatalogTestVersion(PG_VERSION_11)),
"upgrade db");
TEST_RESULT_VOID( TEST_RESULT_VOID(
infoBackupSaveFile(infoBackup, storageRepoWrite(), INFO_BACKUP_PATH_FILE_STR, cipherTypeNone, NULL), infoBackupSaveFile(infoBackup, storageRepoWrite(), INFO_BACKUP_PATH_FILE_STR, cipherTypeNone, NULL),
"save backup info"); "save backup info");
@ -823,7 +829,7 @@ testRun(void)
"HINT: has a stanza-create been performed?", "HINT: has a stanza-create been performed?",
testPath(), testPath(), testPath(), testPath()); testPath(), testPath(), testPath(), testPath());
InfoBackup *infoBackup = infoBackupNew(PG_VERSION_10, 6569239123849665999, NULL); InfoBackup *infoBackup = infoBackupNew(PG_VERSION_10, 6569239123849665999, pgCatalogTestVersion(PG_VERSION_10), NULL);
TEST_RESULT_VOID( TEST_RESULT_VOID(
infoBackupSaveFile(infoBackup, storageTest, STRDEF(INFO_BACKUP_FILE), cipherTypeNone, NULL), "save backup info"); infoBackupSaveFile(infoBackup, storageTest, STRDEF(INFO_BACKUP_FILE), cipherTypeNone, NULL), "save backup info");

View File

@ -47,7 +47,10 @@ testRun(void)
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN( TEST_ASSIGN(
infoPg, infoPgSet(infoPgNew(infoPgArchive, NULL), infoPgArchive, PG_VERSION_94, 6569239123849665679), infoPg,
infoPgSet(
infoPgNew(infoPgArchive, NULL), infoPgArchive, PG_VERSION_94, 6569239123849665679,
pgCatalogTestVersion(PG_VERSION_94)),
"infoPgSet - infoPgArchive"); "infoPgSet - infoPgArchive");
TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " 1 history"); TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " 1 history");
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent"); TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
@ -55,20 +58,26 @@ testRun(void)
TEST_RESULT_INT(pgData.id, 1, " id set"); TEST_RESULT_INT(pgData.id, 1, " id set");
TEST_RESULT_UINT(pgData.systemId, 6569239123849665679, " system-id set"); TEST_RESULT_UINT(pgData.systemId, 6569239123849665679, " system-id set");
TEST_RESULT_UINT(pgData.version, PG_VERSION_94, " version set"); TEST_RESULT_UINT(pgData.version, PG_VERSION_94, " version set");
TEST_RESULT_UINT(pgData.catalogVersion, 0, " catalog version not set for archive");
TEST_ASSIGN( TEST_ASSIGN(
infoPg, infoPgSet(infoPg, infoPgArchive, PG_VERSION_95, 6569239123849665999), "infoPgSet - infoPgArchive second db"); infoPg, infoPgSet(infoPg, infoPgArchive, PG_VERSION_95, 6569239123849665999, pgCatalogTestVersion(PG_VERSION_95)),
"infoPgSet - infoPgArchive second db");
TEST_RESULT_INT(infoPgDataTotal(infoPg), 2, " 2 history"); TEST_RESULT_INT(infoPgDataTotal(infoPg), 2, " 2 history");
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent"); TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
pgData = infoPgData(infoPg, infoPgDataCurrentId(infoPg)); pgData = infoPgData(infoPg, infoPgDataCurrentId(infoPg));
TEST_RESULT_INT(pgData.id, 2, " current id updated"); TEST_RESULT_INT(pgData.id, 2, " current id updated");
TEST_RESULT_UINT(pgData.systemId, 6569239123849665999, " system-id updated"); TEST_RESULT_UINT(pgData.systemId, 6569239123849665999, " system-id updated");
TEST_RESULT_UINT(pgData.version, PG_VERSION_95, " version updated"); TEST_RESULT_UINT(pgData.version, PG_VERSION_95, " version updated");
TEST_RESULT_UINT(pgData.catalogVersion, 0, " catalog version not set for archive");
TEST_RESULT_STR(infoCipherPass(infoPgInfo(infoPg)), NULL, " cipherPass not set"); TEST_RESULT_STR(infoCipherPass(infoPgInfo(infoPg)), NULL, " cipherPass not set");
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN( TEST_ASSIGN(
infoPg, infoPgSet(infoPgNew(infoPgBackup, strNew("123xyz")), infoPgBackup, PG_VERSION_94, 6569239123849665679), infoPg,
infoPgSet(
infoPgNew(infoPgBackup, strNew("123xyz")), infoPgBackup, PG_VERSION_94, 6569239123849665679,
pgCatalogTestVersion(PG_VERSION_94)),
"infoPgSet - infoPgBackup"); "infoPgSet - infoPgBackup");
TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " 1 history"); TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " 1 history");
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent"); TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
@ -76,6 +85,7 @@ testRun(void)
TEST_RESULT_INT(pgData.id, 1, " id set"); TEST_RESULT_INT(pgData.id, 1, " id set");
TEST_RESULT_UINT(pgData.systemId, 6569239123849665679, " system-id set"); TEST_RESULT_UINT(pgData.systemId, 6569239123849665679, " system-id set");
TEST_RESULT_UINT(pgData.version, PG_VERSION_94, " version set"); TEST_RESULT_UINT(pgData.version, PG_VERSION_94, " version set");
TEST_RESULT_UINT(pgData.catalogVersion, 201409291, " catalog version updated");
TEST_RESULT_STR_Z(infoCipherPass(infoPgInfo(infoPg)), "123xyz", " cipherPass set"); TEST_RESULT_STR_Z(infoCipherPass(infoPgInfo(infoPg)), "123xyz", " cipherPass set");
} }
@ -194,8 +204,11 @@ testRun(void)
pgDataTest.id = (unsigned int)4294967295; pgDataTest.id = (unsigned int)4294967295;
pgDataTest.version = (unsigned int)4294967295; pgDataTest.version = (unsigned int)4294967295;
pgDataTest.systemId = 18446744073709551615U; pgDataTest.systemId = 18446744073709551615U;
pgDataTest.catalogVersion = 200101011;
TEST_RESULT_STR_Z( TEST_RESULT_STR_Z(
infoPgDataToLog(&pgDataTest), "{id: 4294967295, version: 4294967295, systemId: 18446744073709551615}", infoPgDataToLog(&pgDataTest),
"{id: 4294967295, version: 4294967295, systemId: 18446744073709551615, catalogVersion: 200101011}",
" check max format"); " check max format");
} }
} }

View File

@ -278,7 +278,10 @@ testRun(void)
strLstAddZ(exclusionList, "bogus/"); strLstAddZ(exclusionList, "bogus/");
Manifest *manifest = NULL; Manifest *manifest = NULL;
TEST_ASSIGN(manifest, manifestNewBuild(storagePg, PG_VERSION_83, false, false, exclusionList, NULL), "build manifest"); TEST_ASSIGN(
manifest,
manifestNewBuild(storagePg, PG_VERSION_83, pgCatalogTestVersion(PG_VERSION_83), false, false, exclusionList, NULL),
"build manifest");
Buffer *contentSave = bufNew(0); Buffer *contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest"); TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
@ -401,7 +404,9 @@ testRun(void)
BUFSTRDEF("TEMP_RELATION")); BUFSTRDEF("TEMP_RELATION"));
// Test manifest - mode stored for shared cluster tablespace dir, pg_xlog contents ignored because online // Test manifest - mode stored for shared cluster tablespace dir, pg_xlog contents ignored because online
TEST_ASSIGN(manifest, manifestNewBuild(storagePg, PG_VERSION_84, true, false, NULL, NULL), "build manifest"); TEST_ASSIGN(
manifest, manifestNewBuild(storagePg, PG_VERSION_84, pgCatalogTestVersion(PG_VERSION_84), true, false, NULL, NULL),
"build manifest");
contentSave = bufNew(0); contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest"); TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
@ -514,7 +519,9 @@ testRun(void)
varLstAdd(tablespaceList, varNewVarLst(tablespace)); varLstAdd(tablespaceList, varNewVarLst(tablespace));
// Test tablespace error // Test tablespace error
TEST_ERROR(manifestNewBuild(storagePg, PG_VERSION_90, false, false, NULL, tablespaceList), AssertError, TEST_ERROR(
manifestNewBuild(storagePg, PG_VERSION_90, pgCatalogTestVersion(PG_VERSION_90), false, false, NULL, tablespaceList),
AssertError,
"tablespace with oid 1 not found in tablespace map\n" "tablespace with oid 1 not found in tablespace map\n"
"HINT: was a tablespace created or dropped during the backup?"); "HINT: was a tablespace created or dropped during the backup?");
@ -525,7 +532,10 @@ testRun(void)
varLstAdd(tablespaceList, varNewVarLst(tablespace)); varLstAdd(tablespaceList, varNewVarLst(tablespace));
// Test manifest - temp tables and pg_notify files ignored // Test manifest - temp tables and pg_notify files ignored
TEST_ASSIGN(manifest, manifestNewBuild(storagePg, PG_VERSION_90, false, false, NULL, tablespaceList), "build manifest"); TEST_ASSIGN(
manifest,
manifestNewBuild(storagePg, PG_VERSION_90, pgCatalogTestVersion(PG_VERSION_90), false, false, NULL, tablespaceList),
"build manifest");
contentSave = bufNew(0); contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest"); TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
@ -616,7 +626,9 @@ testRun(void)
BUFSTRDEF("WALDATA")); BUFSTRDEF("WALDATA"));
// Test manifest - temp tables, unlogged tables, pg_serial and pg_xlog files ignored // Test manifest - temp tables, unlogged tables, pg_serial and pg_xlog files ignored
TEST_ASSIGN(manifest, manifestNewBuild(storagePg, PG_VERSION_91, true, false, NULL, NULL), "build manifest"); TEST_ASSIGN(
manifest, manifestNewBuild(storagePg, PG_VERSION_91, pgCatalogTestVersion(PG_VERSION_91), true, false, NULL, NULL),
"build manifest");
contentSave = bufNew(0); contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest"); TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
@ -699,7 +711,9 @@ testRun(void)
NULL); NULL);
// Test manifest - pg_snapshots files ignored // Test manifest - pg_snapshots files ignored
TEST_ASSIGN(manifest, manifestNewBuild(storagePg, PG_VERSION_92, false, false, NULL, NULL), "build manifest"); TEST_ASSIGN(
manifest, manifestNewBuild(storagePg, PG_VERSION_92, pgCatalogTestVersion(PG_VERSION_92), false, false, NULL, NULL),
"build manifest");
contentSave = bufNew(0); contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest"); TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
@ -839,7 +853,9 @@ testRun(void)
BUFSTRDEF("TESTDATA")); BUFSTRDEF("TESTDATA"));
// Test manifest - pg_dynshmem, pg_replslot and postgresql.auto.conf.tmp files ignored // Test manifest - pg_dynshmem, pg_replslot and postgresql.auto.conf.tmp files ignored
TEST_ASSIGN(manifest, manifestNewBuild(storagePg, PG_VERSION_94, false, true, NULL, NULL), "build manifest"); TEST_ASSIGN(
manifest, manifestNewBuild(storagePg, PG_VERSION_94, pgCatalogTestVersion(PG_VERSION_94), false, true, NULL, NULL),
"build manifest");
contentSave = bufNew(0); contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest"); TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
@ -933,7 +949,8 @@ testRun(void)
// Tablespace link errors when correct verion not found // Tablespace link errors when correct verion not found
TEST_ERROR_FMT( TEST_ERROR_FMT(
manifestNewBuild(storagePg, PG_VERSION_12, false, false, NULL, NULL), FileOpenError, manifestNewBuild(storagePg, PG_VERSION_12, pgCatalogTestVersion(PG_VERSION_12), false, false, NULL, NULL),
FileOpenError,
"unable to get info for missing path/file '%s/pg/pg_tblspc/1/PG_12_201909212': [2] No such file or directory", "unable to get info for missing path/file '%s/pg/pg_tblspc/1/PG_12_201909212': [2] No such file or directory",
testPath()); testPath());
@ -960,7 +977,9 @@ testRun(void)
// Test manifest - 'pg_data/pg_tblspc' will appear in manifest but 'pg_tblspc' will not (no links). Recovery signal files // Test manifest - 'pg_data/pg_tblspc' will appear in manifest but 'pg_tblspc' will not (no links). Recovery signal files
// and backup_label ignored. Old recovery files and pg_xlog are now just another file/directory and will not be ignored. // and backup_label ignored. Old recovery files and pg_xlog are now just another file/directory and will not be ignored.
// pg_wal contents will be ignored online. pg_clog pgVersion > 10 master:true, pg_xact pgVersion > 10 master:false // pg_wal contents will be ignored online. pg_clog pgVersion > 10 master:true, pg_xact pgVersion > 10 master:false
TEST_ASSIGN(manifest, manifestNewBuild(storagePg, PG_VERSION_12, true, false, NULL, NULL), "build manifest"); TEST_ASSIGN(
manifest, manifestNewBuild(storagePg, PG_VERSION_12, pgCatalogTestVersion(PG_VERSION_12), true, false, NULL, NULL),
"build manifest");
contentSave = bufNew(0); contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest"); TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
@ -1030,7 +1049,9 @@ testRun(void)
TEST_TITLE("run 13, offline"); TEST_TITLE("run 13, offline");
// pg_wal not ignored // pg_wal not ignored
TEST_ASSIGN(manifest, manifestNewBuild(storagePg, PG_VERSION_13, false, false, NULL, NULL), "build manifest"); TEST_ASSIGN(
manifest, manifestNewBuild(storagePg, PG_VERSION_13, pgCatalogTestVersion(PG_VERSION_13), false, false, NULL, NULL),
"build manifest");
contentSave = bufNew(0); contentSave = bufNew(0);
TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest"); TEST_RESULT_VOID(manifestSave(manifest, ioBufferWriteNew(contentSave)), "save manifest");
@ -1102,8 +1123,8 @@ testRun(void)
FileOpenError, "unable to create symlink"); FileOpenError, "unable to create symlink");
TEST_ERROR( TEST_ERROR(
manifestNewBuild(storagePg, PG_VERSION_94, false, false, NULL, NULL), LinkDestinationError, manifestNewBuild(storagePg, PG_VERSION_94, pgCatalogTestVersion(PG_VERSION_94), false, false, NULL, NULL),
hrnReplaceKey("link 'link' destination '{[path]}/pg/base' is in PGDATA")); LinkDestinationError, hrnReplaceKey("link 'link' destination '{[path]}/pg/base' is in PGDATA"));
THROW_ON_SYS_ERROR( THROW_ON_SYS_ERROR(
unlink(strZ(strNewFmt("%s/pg/link", testPath()))) == -1, FileRemoveError, "unable to remove symlink"); unlink(strZ(strNewFmt("%s/pg/link", testPath()))) == -1, FileRemoveError, "unable to remove symlink");
@ -1114,8 +1135,8 @@ testRun(void)
storagePathCreateP(storagePgWrite, strNew(MANIFEST_TARGET_PGTBLSPC "/somedir"), .mode = 0700, .noParentCreate = true); storagePathCreateP(storagePgWrite, strNew(MANIFEST_TARGET_PGTBLSPC "/somedir"), .mode = 0700, .noParentCreate = true);
TEST_ERROR( TEST_ERROR(
manifestNewBuild(storagePg, PG_VERSION_94, false, false, NULL, NULL), LinkExpectedError, manifestNewBuild(storagePg, PG_VERSION_94, pgCatalogTestVersion(PG_VERSION_94), false, false, NULL, NULL),
"'pg_data/pg_tblspc/somedir' is not a symlink - pg_tblspc should contain only symlinks"); LinkExpectedError, "'pg_data/pg_tblspc/somedir' is not a symlink - pg_tblspc should contain only symlinks");
storagePathRemoveP(storagePgWrite, strNew(MANIFEST_TARGET_PGTBLSPC "/somedir")); storagePathRemoveP(storagePgWrite, strNew(MANIFEST_TARGET_PGTBLSPC "/somedir"));
@ -1125,8 +1146,8 @@ testRun(void)
storagePutP(storageNewWriteP(storagePgWrite, strNew(MANIFEST_TARGET_PGTBLSPC "/somefile")), NULL); storagePutP(storageNewWriteP(storagePgWrite, strNew(MANIFEST_TARGET_PGTBLSPC "/somefile")), NULL);
TEST_ERROR( TEST_ERROR(
manifestNewBuild(storagePg, PG_VERSION_94, false, false, NULL, NULL), LinkExpectedError, manifestNewBuild(storagePg, PG_VERSION_94, pgCatalogTestVersion(PG_VERSION_94), false, false, NULL, NULL),
"'pg_data/pg_tblspc/somefile' is not a symlink - pg_tblspc should contain only symlinks"); LinkExpectedError, "'pg_data/pg_tblspc/somefile' is not a symlink - pg_tblspc should contain only symlinks");
storageRemoveP(storagePgWrite, strNew(MANIFEST_TARGET_PGTBLSPC "/somefile")); storageRemoveP(storagePgWrite, strNew(MANIFEST_TARGET_PGTBLSPC "/somefile"));
@ -1138,7 +1159,7 @@ testRun(void)
"unable to create symlink"); "unable to create symlink");
TEST_ERROR( TEST_ERROR(
manifestNewBuild(storagePg, PG_VERSION_94, false, true, NULL, NULL), FileOpenError, manifestNewBuild(storagePg, PG_VERSION_94, pgCatalogTestVersion(PG_VERSION_94), false, true, NULL, NULL), FileOpenError,
hrnReplaceKey("unable to get info for missing path/file '{[path]}/pg/link-to-link': [2] No such file or directory")); hrnReplaceKey("unable to get info for missing path/file '{[path]}/pg/link-to-link': [2] No such file or directory"));
THROW_ON_SYS_ERROR( THROW_ON_SYS_ERROR(
@ -1156,8 +1177,8 @@ testRun(void)
FileOpenError, "unable to create symlink"); FileOpenError, "unable to create symlink");
TEST_ERROR_FMT( TEST_ERROR_FMT(
manifestNewBuild(storagePg, PG_VERSION_94, false, false, NULL, NULL), LinkDestinationError, manifestNewBuild(storagePg, PG_VERSION_94, pgCatalogTestVersion(PG_VERSION_94), false, false, NULL, NULL),
"link '%s/pg/linktolink' cannot reference another link '%s/linktest'", testPath(), testPath()); LinkDestinationError, "link '%s/pg/linktolink' cannot reference another link '%s/linktest'", testPath(), testPath());
#undef TEST_MANIFEST_HEADER #undef TEST_MANIFEST_HEADER
#undef TEST_MANIFEST_DB_83 #undef TEST_MANIFEST_DB_83
@ -1267,6 +1288,7 @@ testRun(void)
Manifest *manifest = manifestNewInternal(); Manifest *manifest = manifestNewInternal();
manifest->info = infoNew(NULL); manifest->info = infoNew(NULL);
manifest->data.pgVersion = PG_VERSION_96; manifest->data.pgVersion = PG_VERSION_96;
manifest->data.pgCatalogVersion = pgCatalogTestVersion(PG_VERSION_96);
manifest->data.backupOptionDelta = BOOL_FALSE_VAR; manifest->data.backupOptionDelta = BOOL_FALSE_VAR;
manifestTargetAdd(manifest, &(ManifestTarget){.name = MANIFEST_TARGET_PGDATA_STR, .path = STRDEF("/pg")}); manifestTargetAdd(manifest, &(ManifestTarget){.name = MANIFEST_TARGET_PGDATA_STR, .path = STRDEF("/pg")});

View File

@ -238,8 +238,8 @@ testRun(void)
MEM_CONTEXT_BEGIN(testContext) MEM_CONTEXT_BEGIN(testContext)
{ {
TEST_ASSIGN( TEST_ASSIGN(
manifest, manifestNewBuild(storagePg, PG_VERSION_91, false, false, NULL, NULL), "build with %" PRIu64 " files", manifest, manifestNewBuild(storagePg, PG_VERSION_91, 999999999, false, false, NULL, NULL),
driver.fileTotal); "build with %" PRIu64 " files", driver.fileTotal);
} }
MEM_CONTEXT_END(); MEM_CONTEXT_END();

View File

@ -30,15 +30,11 @@ testRun(void)
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************
if (testBegin("pgControlVersion() and pgCatalogVersion()")) if (testBegin("pgControlVersion()"))
{ {
TEST_ERROR(pgControlVersion(70300), AssertError, "invalid PostgreSQL version 70300"); TEST_ERROR(pgControlVersion(70300), AssertError, "invalid PostgreSQL version 70300");
TEST_RESULT_UINT(pgControlVersion(PG_VERSION_83), 833, "8.3 control version"); TEST_RESULT_UINT(pgControlVersion(PG_VERSION_83), 833, "8.3 control version");
TEST_RESULT_UINT(pgControlVersion(PG_VERSION_11), 1100, "11 control version"); TEST_RESULT_UINT(pgControlVersion(PG_VERSION_11), 1100, "11 control version");
TEST_ERROR(pgCatalogVersion(70900), AssertError, "invalid PostgreSQL version 70900");
TEST_RESULT_UINT(pgCatalogVersion(PG_VERSION_83), 200711281, "8.3 catalog version");
TEST_RESULT_UINT(pgCatalogVersion(PG_VERSION_11), 201809051, "11 catalog version");
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************
@ -78,6 +74,7 @@ testRun(void)
TEST_ASSIGN(info, pgControlFromFile(storageTest), "get control info v11"); TEST_ASSIGN(info, pgControlFromFile(storageTest), "get control info v11");
TEST_RESULT_UINT(info.systemId, 0xFACEFACE, " check system id"); TEST_RESULT_UINT(info.systemId, 0xFACEFACE, " check system id");
TEST_RESULT_UINT(info.version, PG_VERSION_11, " check version"); TEST_RESULT_UINT(info.version, PG_VERSION_11, " check version");
TEST_RESULT_UINT(info.catalogVersion, 201809051, " check catalog version");
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
storagePutP( storagePutP(
@ -97,11 +94,14 @@ testRun(void)
//-------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------
storagePutP( storagePutP(
storageNewWriteP(storageTest, controlFile), storageNewWriteP(storageTest, controlFile),
pgControlTestToBuffer((PgControl){.version = PG_VERSION_83, .systemId = 0xEFEFEFEFEF})); pgControlTestToBuffer(
(PgControl){
.version = PG_VERSION_83, .systemId = 0xEFEFEFEFEF, .catalogVersion = pgCatalogTestVersion(PG_VERSION_83)}));
TEST_ASSIGN(info, pgControlFromFile(storageTest), "get control info v83"); TEST_ASSIGN(info, pgControlFromFile(storageTest), "get control info v83");
TEST_RESULT_UINT(info.systemId, 0xEFEFEFEFEF, " check system id"); TEST_RESULT_UINT(info.systemId, 0xEFEFEFEFEF, " check system id");
TEST_RESULT_UINT(info.version, PG_VERSION_83, " check version"); TEST_RESULT_UINT(info.version, PG_VERSION_83, " check version");
TEST_RESULT_UINT(info.catalogVersion, 200711281, " check catalog version");
} }
// ***************************************************************************************************************************** // *****************************************************************************************************************************
@ -169,10 +169,9 @@ testRun(void)
TEST_RESULT_STR_Z(pgLsnName(PG_VERSION_96), "location", "check location name"); TEST_RESULT_STR_Z(pgLsnName(PG_VERSION_96), "location", "check location name");
TEST_RESULT_STR_Z(pgLsnName(PG_VERSION_10), "lsn", "check lsn name"); TEST_RESULT_STR_Z(pgLsnName(PG_VERSION_10), "lsn", "check lsn name");
TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_84), NULL, "check 8.4 tablespace id"); TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_84, 200904091), NULL, "check 8.4 tablespace id");
TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_90), "PG_9.0_201008051", "check 9.0 tablespace id"); TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_90, 201008051), "PG_9.0_201008051", "check 9.0 tablespace id");
TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_94), "PG_9.4_201409291", "check 9.4 tablespace id"); TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_94, 999999999), "PG_9.4_999999999", "check 9.4 tablespace id");
TEST_RESULT_STR_Z(pgTablespaceId(PG_VERSION_11), "PG_11_201809051", "check 11 tablespace id");
TEST_RESULT_STR_Z(pgWalName(PG_VERSION_96), "xlog", "check xlog name"); TEST_RESULT_STR_Z(pgWalName(PG_VERSION_96), "xlog", "check xlog name");
TEST_RESULT_STR_Z(pgWalName(PG_VERSION_10), "wal", "check wal name"); TEST_RESULT_STR_Z(pgWalName(PG_VERSION_10), "wal", "check wal name");