1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2026-10-23 21:28:56 +03:00

Remove most references to PostgreSQL control and catalog versions.

The control and catalog versions were stored a variety of places in the optimistic hope that they would be useful.  In fact they never were.

We can't remove them from the backup.info and backup.manifest files due to backwards compatibility concerns, but we can at least avoid loading and storing them in C structures.

Add functions to the PostgreSQL interface which will return the control and catalog versions for any supported version of PostgreSQL to allow backwards compatibility for backup.info and backup.manifest.  These functions will be useful in other ways, e.g. generating the tablespace identifier in PostgreSQL >= 9.0.
This commit is contained in:
David Steele
2019-09-07 18:04:39 -04:00
parent 843a602080
commit 0a96764cb8
16 changed files with 214 additions and 153 deletions

View File

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

View File

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

View File

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

View File

@@ -84,19 +84,15 @@ infoBackupNewInternal(void)
Create new object without loading it from a file
***********************************************************************************************************************************/
InfoBackup *
infoBackupNew(
unsigned int pgVersion, uint64_t pgSystemId, const uint32_t pgControlVersion, const uint32_t pgCatalogVersion,
const String *cipherPassSub)
infoBackupNew(unsigned int pgVersion, uint64_t pgSystemId, const String *cipherPassSub)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(UINT, pgVersion);
FUNCTION_LOG_PARAM(UINT64, pgSystemId);
FUNCTION_LOG_PARAM(UINT32, pgControlVersion);
FUNCTION_LOG_PARAM(UINT32, pgCatalogVersion);
FUNCTION_TEST_PARAM(STRING, cipherPassSub);
FUNCTION_LOG_END();
ASSERT(pgVersion > 0 && pgSystemId > 0 && pgControlVersion > 0 && pgCatalogVersion > 0);
ASSERT(pgVersion > 0 && pgSystemId > 0);
InfoBackup *this = NULL;
@@ -106,7 +102,7 @@ infoBackupNew(
// Initialize the pg data
this->infoPg = infoPgNew(infoPgBackup, cipherPassSub);
infoBackupPgSet(this, pgVersion, pgSystemId, pgControlVersion, pgCatalogVersion);
infoBackupPgSet(this, pgVersion, pgSystemId);
}
MEM_CONTEXT_NEW_END();
@@ -307,17 +303,15 @@ infoBackupPg(const InfoBackup *this)
Set the infoPg data
***********************************************************************************************************************************/
InfoBackup *
infoBackupPgSet(InfoBackup *this, unsigned int pgVersion, uint64_t pgSystemId, uint32_t pgControlVersion, uint32_t pgCatalogVersion)
infoBackupPgSet(InfoBackup *this, unsigned int pgVersion, uint64_t pgSystemId)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(INFO_BACKUP, this);
FUNCTION_LOG_PARAM(UINT, pgVersion);
FUNCTION_LOG_PARAM(UINT64, pgSystemId);
FUNCTION_LOG_PARAM(UINT32, pgControlVersion);
FUNCTION_LOG_PARAM(UINT32, pgCatalogVersion);
FUNCTION_LOG_END();
this->infoPg = infoPgSet(this->infoPg, infoPgBackup, pgVersion, pgSystemId, pgControlVersion, pgCatalogVersion);
this->infoPg = infoPgSet(this->infoPg, infoPgBackup, pgVersion, pgSystemId);
FUNCTION_LOG_RETURN(INFO_BACKUP, this);
}

View File

@@ -59,17 +59,14 @@ typedef struct InfoBackupData
/***********************************************************************************************************************************
Constructors
***********************************************************************************************************************************/
InfoBackup *infoBackupNew(
unsigned int pgVersion, uint64_t pgSystemId, const uint32_t pgControlVersion, const uint32_t pgCatalogVersion,
const String *cipherPassSub);
InfoBackup *infoBackupNew(unsigned int pgVersion, uint64_t pgSystemId, const String *cipherPassSub);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
// Remove a backup from the current section
void infoBackupDataDelete(const InfoBackup *this, const String *backupDeleteLabel);
InfoBackup *infoBackupPgSet(
InfoBackup *this, unsigned int pgVersion, uint64_t pgSystemId, uint32_t pgControlVersion, uint32_t pgCatalogVersion);
InfoBackup *infoBackupPgSet(InfoBackup *this, unsigned int pgVersion, uint64_t pgSystemId);
/***********************************************************************************************************************************
Getters

View File

@@ -140,15 +140,6 @@ infoPgLoadCallback(void *data, const String *section, const String *key, const S
kvGet(pgDataKv, loadData->infoPg->type == infoPgArchive ? INFO_KEY_DB_ID_VAR : INFO_KEY_DB_SYSTEM_ID_VAR)),
};
// Get values that are only in backup info files. These are really vestigial since stanza-create verifies the control and
// catalog versions so there is no good reason to store them. However, for backward compatibility we must write them at
// least, even if we give up reading them.
if (loadData->infoPg->type == infoPgBackup)
{
infoPgData.catalogVersion = varUIntForce(kvGet(pgDataKv, INFO_KEY_DB_CATALOG_VERSION_VAR));
infoPgData.controlVersion = varUIntForce(kvGet(pgDataKv, INFO_KEY_DB_CONTROL_VERSION_VAR));
}
// Insert at beginning of list so the history is reverse ordered
lstInsert(loadData->infoPg->history, 0, &infoPgData);
}
@@ -237,17 +228,13 @@ infoPgAdd(InfoPg *this, const InfoPgData *infoPgData)
Set the InfoPg object data based on values passed
***********************************************************************************************************************************/
InfoPg *
infoPgSet(
InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId, const uint32_t pgControlVersion,
const uint32_t pgCatalogVersion)
infoPgSet(InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(INFO_PG, this);
FUNCTION_LOG_PARAM(ENUM, type);
FUNCTION_LOG_PARAM(UINT, pgVersion);
FUNCTION_LOG_PARAM(UINT64, pgSystemId);
FUNCTION_LOG_PARAM(UINT32, pgControlVersion);
FUNCTION_TEST_PARAM(UINT32, pgCatalogVersion);
FUNCTION_LOG_END();
ASSERT(this != NULL);
@@ -270,14 +257,6 @@ infoPgSet(
.systemId = pgSystemId,
};
if (type == infoPgBackup)
{
infoPgData.catalogVersion = pgCatalogVersion;
infoPgData.controlVersion = pgControlVersion;
}
else if (type != infoPgArchive)
THROW_FMT(AssertError, "invalid InfoPg type %u", type);
// Add the pg data to the history list
infoPgAdd(this, &infoPgData);
}
@@ -318,12 +297,15 @@ infoPgSaveCallback(void *data, const String *sectionNext, InfoSave *infoSaveData
InfoPgData pgData = infoPgDataCurrent(saveData->infoPg);
// These need to be saved because older Perl and C versions expect them
if (saveData->infoPg->type == infoPgBackup)
{
infoSaveValue(
infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_CATALOG_VERSION_VAR), jsonFromUInt(pgData.catalogVersion));
infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_CATALOG_VERSION_VAR),
jsonFromUInt(pgCatalogVersion(pgData.version)));
infoSaveValue(
infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_CONTROL_VERSION_VAR), jsonFromUInt(pgData.controlVersion));
infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_CONTROL_VERSION_VAR),
jsonFromUInt(pgControlVersion(pgData.version)));
}
infoSaveValue(infoSaveData, INFO_SECTION_DB_STR, varStr(INFO_KEY_DB_ID_VAR), jsonFromUInt(pgData.id));
@@ -347,9 +329,11 @@ infoPgSaveCallback(void *data, const String *sectionNext, InfoSave *infoSaveData
if (saveData->infoPg->type == infoPgBackup)
{
kvPut(pgDataKv, INFO_KEY_DB_CATALOG_VERSION_VAR, VARUINT(pgData.catalogVersion));
kvPut(pgDataKv, INFO_KEY_DB_CONTROL_VERSION_VAR, VARUINT(pgData.controlVersion));
kvPut(pgDataKv, INFO_KEY_DB_SYSTEM_ID_VAR, VARUINT64(pgData.systemId));
// These need to be saved because older Perl and C versions expect them
kvPut(pgDataKv, INFO_KEY_DB_CATALOG_VERSION_VAR, VARUINT(pgCatalogVersion(pgData.version)));
kvPut(pgDataKv, INFO_KEY_DB_CONTROL_VERSION_VAR, VARUINT(pgControlVersion(pgData.version)));
}
else
kvPut(pgDataKv, INFO_KEY_DB_ID_VAR, VARUINT64(pgData.systemId));
@@ -527,7 +511,5 @@ Render as string for logging
String *
infoPgDataToLog(const InfoPgData *this)
{
return strNewFmt(
"{id: %u, version: %u, systemId: %" PRIu64 ", catalogVersion: %" PRIu32 ", controlVersion: %" PRIu32 "}",
this->id, this->version, this->systemId, this->catalogVersion, this->controlVersion);
return strNewFmt("{id: %u, version: %u, systemId: %" PRIu64 "}", this->id, this->version, this->systemId);
}

View File

@@ -32,8 +32,6 @@ typedef struct InfoPgData
{
unsigned int id;
uint64_t systemId;
uint32_t catalogVersion;
uint32_t controlVersion;
unsigned int version;
} InfoPgData;
@@ -56,9 +54,7 @@ InfoPg *infoPgNewLoad(IoRead *read, InfoPgType type, InfoLoadNewCallback *callba
Functions
***********************************************************************************************************************************/
void infoPgAdd(InfoPg *this, const InfoPgData *infoPgData);
InfoPg *infoPgSet(
InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId, const uint32_t pgControlVersion,
const uint32_t pgCatalogVersion);
InfoPg *infoPgSet(InfoPg *this, InfoPgType type, const unsigned int pgVersion, const uint64_t pgSystemId);
void infoPgSave(InfoPg *this, IoWrite *write, InfoSaveCallback *callbackFunction, void *callbackData);
/***********************************************************************************************************************************

View File

@@ -58,12 +58,18 @@ typedef struct PgInterface
// Version of PostgreSQL supported by this interface
unsigned int version;
// Get the catalog version for this version of PostgreSQL
uint32_t (*catalogVersion)(void);
// Does pg_control match this version of PostgreSQL?
bool (*controlIs)(const unsigned char *);
// Convert pg_control to a common data structure
PgControl (*control)(const unsigned char *);
// Get the control version for this version of PostgreSQL
uint32_t (*controlVersion)(void);
// Does the WAL header match this version of PostgreSQL?
bool (*walIs)(const unsigned char *);
@@ -85,8 +91,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_11,
.catalogVersion = pgInterfaceCatalogVersion110,
.controlIs = pgInterfaceControlIs110,
.control = pgInterfaceControl110,
.controlVersion = pgInterfaceControlVersion110,
.walIs = pgInterfaceWalIs110,
.wal = pgInterfaceWal110,
@@ -99,8 +108,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_10,
.catalogVersion = pgInterfaceCatalogVersion100,
.controlIs = pgInterfaceControlIs100,
.control = pgInterfaceControl100,
.controlVersion = pgInterfaceControlVersion100,
.walIs = pgInterfaceWalIs100,
.wal = pgInterfaceWal100,
@@ -113,8 +125,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_96,
.catalogVersion = pgInterfaceCatalogVersion096,
.controlIs = pgInterfaceControlIs096,
.control = pgInterfaceControl096,
.controlVersion = pgInterfaceControlVersion096,
.walIs = pgInterfaceWalIs096,
.wal = pgInterfaceWal096,
@@ -127,8 +142,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_95,
.catalogVersion = pgInterfaceCatalogVersion095,
.controlIs = pgInterfaceControlIs095,
.control = pgInterfaceControl095,
.controlVersion = pgInterfaceControlVersion095,
.walIs = pgInterfaceWalIs095,
.wal = pgInterfaceWal095,
@@ -141,8 +159,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_94,
.catalogVersion = pgInterfaceCatalogVersion094,
.controlIs = pgInterfaceControlIs094,
.control = pgInterfaceControl094,
.controlVersion = pgInterfaceControlVersion094,
.walIs = pgInterfaceWalIs094,
.wal = pgInterfaceWal094,
@@ -155,8 +176,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_93,
.catalogVersion = pgInterfaceCatalogVersion093,
.controlIs = pgInterfaceControlIs093,
.control = pgInterfaceControl093,
.controlVersion = pgInterfaceControlVersion093,
.walIs = pgInterfaceWalIs093,
.wal = pgInterfaceWal093,
@@ -169,8 +193,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_92,
.catalogVersion = pgInterfaceCatalogVersion092,
.controlIs = pgInterfaceControlIs092,
.control = pgInterfaceControl092,
.controlVersion = pgInterfaceControlVersion092,
.walIs = pgInterfaceWalIs092,
.wal = pgInterfaceWal092,
@@ -183,8 +210,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_91,
.catalogVersion = pgInterfaceCatalogVersion091,
.controlIs = pgInterfaceControlIs091,
.control = pgInterfaceControl091,
.controlVersion = pgInterfaceControlVersion091,
.walIs = pgInterfaceWalIs091,
.wal = pgInterfaceWal091,
@@ -197,8 +227,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_90,
.catalogVersion = pgInterfaceCatalogVersion090,
.controlIs = pgInterfaceControlIs090,
.control = pgInterfaceControl090,
.controlVersion = pgInterfaceControlVersion090,
.walIs = pgInterfaceWalIs090,
.wal = pgInterfaceWal090,
@@ -211,8 +244,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_84,
.catalogVersion = pgInterfaceCatalogVersion084,
.controlIs = pgInterfaceControlIs084,
.control = pgInterfaceControl084,
.controlVersion = pgInterfaceControlVersion084,
.walIs = pgInterfaceWalIs084,
.wal = pgInterfaceWal084,
@@ -225,8 +261,11 @@ static const PgInterface pgInterface[] =
{
.version = PG_VERSION_83,
.catalogVersion = pgInterfaceCatalogVersion083,
.controlIs = pgInterfaceControlIs083,
.control = pgInterfaceControl083,
.controlVersion = pgInterfaceControlVersion083,
.walIs = pgInterfaceWalIs083,
.wal = pgInterfaceWal083,
@@ -252,6 +291,47 @@ typedef struct PgControlCommon
uint32_t catalogVersion;
} PgControlCommon;
/***********************************************************************************************************************************
Get the interface for a PostgreSQL version
***********************************************************************************************************************************/
static const PgInterface *
pgInterfaceVersion(unsigned int pgVersion)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, pgVersion);
FUNCTION_TEST_END();
const PgInterface *result = NULL;
for (unsigned int interfaceIdx = 0; interfaceIdx < PG_INTERFACE_SIZE; interfaceIdx++)
{
if (pgInterface[interfaceIdx].version == pgVersion)
{
result = &pgInterface[interfaceIdx];
break;
}
}
// If the version was not found then error
if (result == NULL)
THROW_FMT(AssertError, "invalid " PG_NAME " version %u", pgVersion);
FUNCTION_TEST_RETURN(result);
}
/***********************************************************************************************************************************
Get the catalog version for a PostgreSQL version
***********************************************************************************************************************************/
uint32_t
pgCatalogVersion(unsigned int pgVersion)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, pgVersion);
FUNCTION_TEST_END();
FUNCTION_TEST_RETURN(pgInterfaceVersion(pgVersion)->catalogVersion());
}
/***********************************************************************************************************************************
Get info from pg_control
***********************************************************************************************************************************/
@@ -337,6 +417,19 @@ pgControlFromFile(const Storage *storage, const String *pgPath)
FUNCTION_LOG_RETURN(PG_CONTROL, result);
}
/***********************************************************************************************************************************
Get the control version for a PostgreSQL version
***********************************************************************************************************************************/
uint32_t
pgControlVersion(unsigned int pgVersion)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, pgVersion);
FUNCTION_TEST_END();
FUNCTION_TEST_RETURN(pgInterfaceVersion(pgVersion)->controlVersion());
}
/***********************************************************************************************************************************
These WAL header fields are common to all versions of PostgreSQL, so we can use them to generate error messages when the WAL magic
cannot be found.
@@ -454,28 +547,19 @@ pgControlTestToBuffer(PgControl pgControl)
memset(bufPtr(result), 0, bufSize(result));
bufUsedSet(result, bufSize(result));
// Find the interface for the version of PostgreSQL
const PgInterface *interface = NULL;
for (unsigned int interfaceIdx = 0; interfaceIdx < PG_INTERFACE_SIZE; interfaceIdx++)
{
if (pgInterface[interfaceIdx].version == pgControl.version)
{
interface = &pgInterface[interfaceIdx];
break;
}
}
// If the version was not found then error
if (interface == NULL)
THROW_FMT(AssertError, "invalid version %u", pgControl.version);
// Generate pg_control
interface->controlTest(pgControl, bufPtr(result));
pgInterfaceVersion(pgControl.version)->controlTest(pgControl, bufPtr(result));
FUNCTION_TEST_RETURN(result);
}
#endif
/***********************************************************************************************************************************
Create WAL for testing
***********************************************************************************************************************************/
#ifdef DEBUG
void
pgWalTestToBuffer(PgWal pgWal, Buffer *walBuffer)
{
@@ -486,24 +570,8 @@ pgWalTestToBuffer(PgWal pgWal, Buffer *walBuffer)
ASSERT(walBuffer != NULL);
// Find the interface for the version of PostgreSQL
const PgInterface *interface = NULL;
for (unsigned int interfaceIdx = 0; interfaceIdx < PG_INTERFACE_SIZE; interfaceIdx++)
{
if (pgInterface[interfaceIdx].version == pgWal.version)
{
interface = &pgInterface[interfaceIdx];
break;
}
}
// If the version was not found then error
if (interface == NULL)
THROW_FMT(AssertError, "invalid version %u", pgWal.version);
// Generate pg_control
interface->walTest(pgWal, bufPtr(walBuffer));
// Generate WAL
pgInterfaceVersion(pgWal.version)->walTest(pgWal, bufPtr(walBuffer));
FUNCTION_TEST_RETURN_VOID();
}

View File

@@ -53,9 +53,6 @@ typedef struct PgControl
unsigned int version;
uint64_t systemId;
uint32_t controlVersion;
uint32_t catalogVersion;
unsigned int pageSize;
unsigned int walSegmentSize;
@@ -74,8 +71,10 @@ typedef struct PgWal
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
uint32_t pgCatalogVersion(unsigned int pgVersion);
PgControl pgControlFromFile(const Storage *storage, const String *pgPath);
PgControl pgControlFromBuffer(const Buffer *controlFile);
uint32_t pgControlVersion(unsigned int pgVersion);
unsigned int pgVersionFromStr(const String *version);
String *pgVersionToStr(unsigned int version);

View File

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

View File

@@ -17,6 +17,22 @@ Each version of PostgreSQL will need a vXXX.c file to contain the version-specif
#include "postgres/interface/version.auto.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
***********************************************************************************************************************************/
@@ -54,8 +70,6 @@ Read the version specific pg_control into a general data structure
return (PgControl) \
{ \
.systemId = ((ControlFileData *)controlFile)->system_identifier, \
.controlVersion = ((ControlFileData *)controlFile)->pg_control_version, \
.catalogVersion = ((ControlFileData *)controlFile)->catalog_version_no, \
.pageSize = ((ControlFileData *)controlFile)->blcksz, \
.walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \
.pageChecksum = ((ControlFileData *)controlFile)->data_checksum_version != 0, \
@@ -74,8 +88,6 @@ Read the version specific pg_control into a general data structure
return (PgControl) \
{ \
.systemId = ((ControlFileData *)controlFile)->system_identifier, \
.controlVersion = ((ControlFileData *)controlFile)->pg_control_version, \
.catalogVersion = ((ControlFileData *)controlFile)->catalog_version_no, \
.pageSize = ((ControlFileData *)controlFile)->blcksz, \
.walSegmentSize = ((ControlFileData *)controlFile)->xlog_seg_size, \
}; \
@@ -83,6 +95,22 @@ Read the version specific pg_control into a general data structure
#endif
/***********************************************************************************************************************************
Get the control version
***********************************************************************************************************************************/
#if PG_VERSION > PG_VERSION_MAX
#elif PG_VERSION >= PG_VERSION_83
#define PG_INTERFACE_CONTROL_VERSION(version) \
uint32_t \
pgInterfaceControlVersion##version(void) \
{ \
return PG_CONTROL_VERSION; \
}
#endif
/***********************************************************************************************************************************
Create a pg_control file for testing
***********************************************************************************************************************************/
@@ -97,10 +125,8 @@ Create a pg_control file for testing
ASSERT(buffer != NULL); \
\
((ControlFileData *)buffer)->system_identifier = pgControl.systemId; \
((ControlFileData *)buffer)->pg_control_version = \
pgControl.controlVersion == 0 ? PG_CONTROL_VERSION : pgControl.controlVersion; \
((ControlFileData *)buffer)->catalog_version_no = \
pgControl.catalogVersion == 0 ? CATALOG_VERSION_NO : pgControl.catalogVersion; \
((ControlFileData *)buffer)->pg_control_version = PG_CONTROL_VERSION; \
((ControlFileData *)buffer)->catalog_version_no = CATALOG_VERSION_NO; \
((ControlFileData *)buffer)->blcksz = pgControl.pageSize; \
((ControlFileData *)buffer)->xlog_seg_size = pgControl.walSegmentSize; \
((ControlFileData *)buffer)->data_checksum_version = pgControl.pageChecksum; \
@@ -116,10 +142,8 @@ Create a pg_control file for testing
ASSERT(!pgControl.pageChecksum); \
\
((ControlFileData *)buffer)->system_identifier = pgControl.systemId; \
((ControlFileData *)buffer)->pg_control_version = \
pgControl.controlVersion == 0 ? PG_CONTROL_VERSION : pgControl.controlVersion; \
((ControlFileData *)buffer)->catalog_version_no = \
pgControl.catalogVersion == 0 ? CATALOG_VERSION_NO : pgControl.catalogVersion; \
((ControlFileData *)buffer)->pg_control_version = PG_CONTROL_VERSION; \
((ControlFileData *)buffer)->catalog_version_no = CATALOG_VERSION_NO; \
((ControlFileData *)buffer)->blcksz = pgControl.pageSize; \
((ControlFileData *)buffer)->xlog_seg_size = pgControl.walSegmentSize; \
}
@@ -188,8 +212,10 @@ Create a WAL file file for testing
Call all macros with a single macro to make the vXXX.c files as simple as possible
***********************************************************************************************************************************/
#define PG_INTERFACE_BASE(version) \
PG_INTERFACE_CATALOG_VERSION(version) \
PG_INTERFACE_CONTROL_IS(version) \
PG_INTERFACE_CONTROL(version) \
PG_INTERFACE_CONTROL_VERSION(version) \
PG_INTERFACE_WAL_IS(version) \
PG_INTERFACE_WAL(version)

View File

@@ -333,7 +333,7 @@ unit:
# ----------------------------------------------------------------------------------------------------------------------------
- name: interface
total: 6
total: 7
coverage:
postgres/interface: full

View File

@@ -734,7 +734,7 @@ testRun(void)
"db-version=\"9.5\"\n"
"\n"
"[db:history]\n"
"1={\"db-catalog-version\":201608131,\"db-control-version\":960,\"db-system-id\":6569239123849665679,"
"1={\"db-catalog-version\":201608131,\"db-control-version\":942,\"db-system-id\":6569239123849665679,"
"\"db-version\":\"9.5\"}\n"
);
TEST_RESULT_VOID(
@@ -753,7 +753,7 @@ testRun(void)
"db-version=\"9.6\"\n"
"\n"
"[db:history]\n"
"1={\"db-catalog-version\":201608131,\"db-control-version\":960,\"db-system-id\":6569239123849665679,"
"1={\"db-catalog-version\":201510051,\"db-control-version\":942,\"db-system-id\":6569239123849665679,"
"\"db-version\":\"9.5\"}\n"
"2={\"db-catalog-version\":201608131,\"db-control-version\":960,\"db-system-id\":6569239123849665679,"
"\"db-version\":\"9.6\"}\n"
@@ -784,7 +784,7 @@ testRun(void)
"db-version=\"9.6\"\n"
"\n"
"[db:history]\n"
"1={\"db-catalog-version\":201608131,\"db-control-version\":960,\"db-system-id\":6569239123849665999,"
"1={\"db-catalog-version\":201510051,\"db-control-version\":942,\"db-system-id\":6569239123849665999,"
"\"db-version\":\"9.5\"}\n"
"2={\"db-catalog-version\":201608131,\"db-control-version\":960,\"db-system-id\":6569239123849665679,"
"\"db-version\":\"9.6\"}\n"

View File

@@ -53,7 +53,7 @@ testRun(void)
Buffer *contentCompare = bufNew(0);
TEST_ASSIGN(
infoBackup, infoBackupNew(PG_VERSION_94, 6569239123849665679, 942, 201409291, NULL),
infoBackup, infoBackupNew(PG_VERSION_94, 6569239123849665679, NULL),
"infoBackupNew() - no cipher sub");
TEST_RESULT_VOID(infoBackupSave(infoBackup, ioBufferWriteNew(contentCompare)), " save backup info from new");
TEST_RESULT_STR(strPtr(strNewBuf(contentCompare)), strPtr(strNewBuf(contentSave)), " check save");
@@ -68,8 +68,7 @@ testRun(void)
TEST_ASSIGN(
infoBackup,
infoBackupNew(
PG_VERSION_10, 6569239123849665999, 1002, 201707211,
strNew("zWa/6Xtp-IVZC5444yXB+cgFDFl7MxGlgkZSaoPvTGirhPygu4jOKOXf9LO4vjfO")),
PG_VERSION_10, 6569239123849665999, strNew("zWa/6Xtp-IVZC5444yXB+cgFDFl7MxGlgkZSaoPvTGirhPygu4jOKOXf9LO4vjfO")),
"infoBackupNew() - cipher sub");
contentSave = bufNew(0);
@@ -86,13 +85,11 @@ testRun(void)
// Add pg info
// -------------------------------------------------------------------------------------------------------------------------
InfoPgData infoPgData = {0};
TEST_RESULT_VOID(infoBackupPgSet(infoBackup, PG_VERSION_94, 6569239123849665679, 12345, 54321), "add another infoPg");
TEST_RESULT_VOID(infoBackupPgSet(infoBackup, PG_VERSION_94, 6569239123849665679), "add another infoPg");
TEST_RESULT_INT(infoPgDataTotal(infoBackup->infoPg), 2, " history incremented");
TEST_ASSIGN(infoPgData, infoPgDataCurrent(infoBackup->infoPg), " get current infoPgData");
TEST_RESULT_INT(infoPgData.version, PG_VERSION_94, " version set");
TEST_RESULT_INT(infoPgData.systemId, 6569239123849665679, " systemId set");
TEST_RESULT_INT(infoPgData.controlVersion, 12345, " catalog set");
TEST_RESULT_INT(infoPgData.catalogVersion, 54321, " catalog set");
// Free
//--------------------------------------------------------------------------------------------------------------------------
@@ -241,7 +238,7 @@ testRun(void)
"HINT: has a stanza-create been performed?",
testPath(), testPath(), testPath(), testPath());
InfoBackup *infoBackup = infoBackupNew(PG_VERSION_10, 6569239123849665999, 1002, 201707211, NULL);
InfoBackup *infoBackup = infoBackupNew(PG_VERSION_10, 6569239123849665999, NULL);
TEST_RESULT_VOID(
infoBackupSaveFile(infoBackup, storageTest, STRDEF(INFO_BACKUP_FILE), cipherTypeNone, NULL), "save backup info");

View File

@@ -47,7 +47,7 @@ testRun(void)
//--------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(
infoPg, infoPgSet(infoPgNew(infoPgArchive, NULL), infoPgArchive, PG_VERSION_94, 6569239123849665679, 0, 0),
infoPg, infoPgSet(infoPgNew(infoPgArchive, NULL), infoPgArchive, PG_VERSION_94, 6569239123849665679),
"infoPgSet - infoPgArchive");
TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " 1 history");
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
@@ -55,40 +55,28 @@ testRun(void)
TEST_RESULT_INT(pgData.id, 1, " id set");
TEST_RESULT_INT(pgData.systemId, 6569239123849665679, " system-id set");
TEST_RESULT_INT(pgData.version, PG_VERSION_94, " version set");
TEST_RESULT_INT(pgData.catalogVersion, 0, " catalog-version not set");
TEST_RESULT_INT(pgData.controlVersion, 0, " control-version set");
TEST_ASSIGN(
infoPg, infoPgSet(infoPg, infoPgArchive, PG_VERSION_95, 6569239123849665999, 0, 0),
"infoPgSet - infoPgArchive second db");
infoPg, infoPgSet(infoPg, infoPgArchive, PG_VERSION_95, 6569239123849665999), "infoPgSet - infoPgArchive second db");
TEST_RESULT_INT(infoPgDataTotal(infoPg), 2, " 2 history");
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
pgData = infoPgData(infoPg, infoPgDataCurrentId(infoPg));
TEST_RESULT_INT(pgData.id, 2, " current id updated");
TEST_RESULT_INT(pgData.systemId, 6569239123849665999, " system-id updated");
TEST_RESULT_INT(pgData.version, PG_VERSION_95, " version updated");
TEST_RESULT_INT(pgData.catalogVersion, 0, " catalog-version not set");
TEST_RESULT_INT(pgData.controlVersion, 0, " control-version not set");
TEST_RESULT_STR(strPtr(infoCipherPass(infoPgInfo(infoPg))), NULL, " cipherPass not set");
//--------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(
infoPg, infoPgSet(infoPgNew(infoPgBackup, strNew("123xyz")), infoPgBackup, PG_VERSION_94, 6569239123849665679,
201409291, 942), "infoPgSet - infoPgBackup");
infoPg, infoPgSet(infoPgNew(infoPgBackup, strNew("123xyz")), infoPgBackup, PG_VERSION_94, 6569239123849665679),
"infoPgSet - infoPgBackup");
TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " 1 history");
TEST_RESULT_INT(infoPgDataCurrentId(infoPg), 0, " 0 historyCurrent");
pgData = infoPgData(infoPg, infoPgDataCurrentId(infoPg));
TEST_RESULT_INT(pgData.id, 1, " id set");
TEST_RESULT_INT(pgData.systemId, 6569239123849665679, " system-id set");
TEST_RESULT_INT(pgData.version, PG_VERSION_94, " version set");
TEST_RESULT_INT(pgData.catalogVersion, 942, " catalog-version set");
TEST_RESULT_INT(pgData.controlVersion, 201409291, " control-version set");
TEST_RESULT_STR(strPtr(infoCipherPass(infoPgInfo(infoPg))), "123xyz", " cipherPass set");
//--------------------------------------------------------------------------------------------------------------------------
TEST_ERROR(
infoPgSet(infoPgNew(infoPgBackup, NULL), 1000, PG_VERSION_94, 6569239123849665679, 201409291, 942),
AssertError, "invalid InfoPg type 1000");
}
// *****************************************************************************************************************************
@@ -132,8 +120,6 @@ testRun(void)
TEST_RESULT_INT(pgData.id, 1, " id set");
TEST_RESULT_INT(pgData.version, PG_VERSION_94, " version set");
TEST_RESULT_INT(pgData.systemId, 6569239123849665679, " system-id set");
TEST_RESULT_INT(pgData.catalogVersion, 0, " catalog-version not set");
TEST_RESULT_INT(pgData.controlVersion, 0, " control-version not set");
TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " check pg data total");
TEST_RESULT_STR(strPtr(infoPgArchiveId(infoPg, 0)), "9.4-1", " check pg archive id");
TEST_RESULT_PTR(infoPgCipherPass(infoPg), NULL, " no cipher passphrase");
@@ -179,15 +165,11 @@ testRun(void)
TEST_RESULT_INT(pgData.id, 2, " id set");
TEST_RESULT_INT(pgData.version, PG_VERSION_95, " version set");
TEST_RESULT_INT(pgData.systemId, 6365925855999999999, " system-id set");
TEST_RESULT_INT(pgData.catalogVersion, 201510051, " catalog-version set");
TEST_RESULT_INT(pgData.controlVersion, 942, " control-version set");
pgData = infoPgData(infoPg, 1);
TEST_RESULT_INT(pgData.id, 1, " id set");
TEST_RESULT_INT(pgData.version, PG_VERSION_94, " version set");
TEST_RESULT_INT(pgData.systemId, 6569239123849665679, " system-id set");
TEST_RESULT_INT(pgData.catalogVersion, 201409291, " catalog-version set");
TEST_RESULT_INT(pgData.controlVersion, 942, " control-version set");
contentSave = bufNew(0);
@@ -201,16 +183,12 @@ testRun(void)
pgData.id = 3;
pgData.version = PG_VERSION_96;
pgData.systemId = 6399999999999999999;
pgData.catalogVersion = 201608131;
pgData.controlVersion = 960;
TEST_RESULT_VOID(infoPgAdd(infoPg, &pgData), "infoPgAdd");
InfoPgData pgDataTest = infoPgDataCurrent(infoPg);
TEST_RESULT_INT(pgDataTest.id, 3, " id set");
TEST_RESULT_INT(pgDataTest.version, PG_VERSION_96, " version set");
TEST_RESULT_INT(pgDataTest.systemId, 6399999999999999999, " system-id set");
TEST_RESULT_INT(pgDataTest.catalogVersion, 201608131, " catalog-version set");
TEST_RESULT_INT(pgDataTest.controlVersion, 960, " control-version set");
// infoPgDataToLog
//--------------------------------------------------------------------------------------------------------------------------
@@ -218,12 +196,8 @@ testRun(void)
pgDataTest.id = (unsigned int)4294967295;
pgDataTest.version = (unsigned int)4294967295;
pgDataTest.systemId = 18446744073709551615U;
pgDataTest.catalogVersion = (uint32_t)4294967295;
pgDataTest.controlVersion = (uint32_t)4294967295;
TEST_RESULT_STR(
strPtr(infoPgDataToLog(&pgDataTest)),
"{id: 4294967295, version: 4294967295, systemId: 18446744073709551615, catalogVersion: 4294967295, controlVersion:"
" 4294967295}",
strPtr(infoPgDataToLog(&pgDataTest)), "{id: 4294967295, version: 4294967295, systemId: 18446744073709551615}",
" check max format");
}
}

View File

@@ -30,6 +30,18 @@ testRun(void)
TEST_RESULT_STR(strPtr(pgVersionToStr(83456)), "8.34", "infoPgVersionToString 83456");
}
// *****************************************************************************************************************************
if (testBegin("pgControlVersion() and pgCatalogVersion()"))
{
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_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");
}
// *****************************************************************************************************************************
if (testBegin("pgControlFromBuffer() and pgControlFromFile()"))
{
@@ -52,7 +64,7 @@ testRun(void)
"unexpected control version = 501 and catalog version = 19780101\nHINT: is this version of PostgreSQL supported?");
//--------------------------------------------------------------------------------------------------------------------------
TEST_ERROR(pgControlTestToBuffer((PgControl){.version = 0}), AssertError, "invalid version 0");
TEST_ERROR(pgControlTestToBuffer((PgControl){.version = 0}), AssertError, "invalid PostgreSQL version 0");
//--------------------------------------------------------------------------------------------------------------------------
storagePutNP(
@@ -62,8 +74,6 @@ testRun(void)
PgControl info = {0};
TEST_ASSIGN(info, pgControlFromFile(storageTest, strNew(testPath())), "get control info v11");
TEST_RESULT_INT(info.systemId, 0xFACEFACE, " check system id");
TEST_RESULT_INT(info.controlVersion, 1100, " check control version");
TEST_RESULT_INT(info.catalogVersion, 201809051, " check catalog version");
TEST_RESULT_INT(info.version, PG_VERSION_11, " check version");
//--------------------------------------------------------------------------------------------------------------------------
@@ -89,8 +99,6 @@ testRun(void)
TEST_ASSIGN(info, pgControlFromFile(storageTest, strNew(testPath())), "get control info v83");
TEST_RESULT_INT(info.systemId, 0xEFEFEFEFEF, " check system id");
TEST_RESULT_INT(info.controlVersion, 833, " check control version");
TEST_RESULT_INT(info.catalogVersion, 200711281, " check catalog version");
TEST_RESULT_INT(info.version, PG_VERSION_83, " check version");
}
@@ -126,7 +134,7 @@ testRun(void)
//--------------------------------------------------------------------------------------------------------------------------
memset(bufPtr(result), 0, bufSize(result));
TEST_ERROR(pgWalTestToBuffer((PgWal){.version = 0}, result), AssertError, "invalid version 0");
TEST_ERROR(pgWalTestToBuffer((PgWal){.version = 0}, result), AssertError, "invalid PostgreSQL version 0");
//--------------------------------------------------------------------------------------------------------------------------
memset(bufPtr(result), 0, bufSize(result));