1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-01 00:25:06 +02: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

@ -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();
}