You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-07-05 00:28:52 +02:00
Add pg-version-force option for fork integration.
Forks may update pg_control version or WAL magic without affecting the structures that pgBackRest depends on. This option forces pgBackRest to treat a cluster as the specified version when it cannot be automatically identified.
This commit is contained in:
@ -111,7 +111,13 @@ pgInterfaceVersion(unsigned int pgVersion)
|
||||
|
||||
// If the version was not found then error
|
||||
if (result == NULL)
|
||||
THROW_FMT(AssertError, "invalid " PG_NAME " version %u", pgVersion);
|
||||
{
|
||||
THROW_FMT(
|
||||
VersionNotSupportedError,
|
||||
"invalid " PG_NAME " version %u\n"
|
||||
"HINT: is this version of PostgreSQL supported?",
|
||||
pgVersion);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_TYPE_CONST_P(PgInterface, result);
|
||||
}
|
||||
@ -172,10 +178,11 @@ pgWalSegmentSizeCheck(unsigned int pgVersion, unsigned int walSegmentSize)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
static PgControl
|
||||
pgControlFromBuffer(const Buffer *controlFile)
|
||||
pgControlFromBuffer(const Buffer *controlFile, const String *const pgVersionForce)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(BUFFER, controlFile);
|
||||
FUNCTION_LOG_PARAM(STRING, pgVersionForce);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(controlFile != NULL);
|
||||
@ -183,28 +190,35 @@ pgControlFromBuffer(const Buffer *controlFile)
|
||||
// Search for the version of PostgreSQL that uses this control file
|
||||
const PgInterface *interface = NULL;
|
||||
|
||||
for (unsigned int interfaceIdx = 0; interfaceIdx < LENGTH_OF(pgInterface); interfaceIdx++)
|
||||
if (pgVersionForce != NULL)
|
||||
interface = pgInterfaceVersion(pgVersionFromStr(pgVersionForce));
|
||||
else
|
||||
{
|
||||
if (pgInterface[interfaceIdx].controlIs(bufPtrConst(controlFile)))
|
||||
for (unsigned int interfaceIdx = 0; interfaceIdx < LENGTH_OF(pgInterface); interfaceIdx++)
|
||||
{
|
||||
interface = &pgInterface[interfaceIdx];
|
||||
break;
|
||||
if (pgInterface[interfaceIdx].controlIs(bufPtrConst(controlFile)))
|
||||
{
|
||||
interface = &pgInterface[interfaceIdx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the version was not found then error with the control and catalog version that were found
|
||||
if (interface == NULL)
|
||||
{
|
||||
const PgControlCommon *controlCommon = (const PgControlCommon *)bufPtrConst(controlFile);
|
||||
|
||||
THROW_FMT(
|
||||
VersionNotSupportedError,
|
||||
"unexpected control version = %u and catalog version = %u\n"
|
||||
"HINT: is this version of PostgreSQL supported?",
|
||||
controlCommon->controlVersion, controlCommon->catalogVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// If the version was not found then error with the control and catalog version that were found
|
||||
if (interface == NULL)
|
||||
{
|
||||
const PgControlCommon *controlCommon = (const PgControlCommon *)bufPtrConst(controlFile);
|
||||
|
||||
THROW_FMT(
|
||||
VersionNotSupportedError,
|
||||
"unexpected control version = %u and catalog version = %u\n"
|
||||
"HINT: is this version of PostgreSQL supported?",
|
||||
controlCommon->controlVersion, controlCommon->catalogVersion);
|
||||
}
|
||||
|
||||
// Get info from the control file
|
||||
ASSERT(pgVersionForce != NULL || interface->controlIs(bufPtrConst(controlFile)));
|
||||
|
||||
PgControl result = interface->control(bufPtrConst(controlFile));
|
||||
result.version = interface->version;
|
||||
|
||||
@ -219,10 +233,11 @@ pgControlFromBuffer(const Buffer *controlFile)
|
||||
}
|
||||
|
||||
FN_EXTERN PgControl
|
||||
pgControlFromFile(const Storage *storage)
|
||||
pgControlFromFile(const Storage *storage, const String *const pgVersionForce)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STORAGE, storage);
|
||||
FUNCTION_LOG_PARAM(STRING, pgVersionForce);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(storage != NULL);
|
||||
@ -235,7 +250,7 @@ pgControlFromFile(const Storage *storage)
|
||||
Buffer *controlFile = storageGetP(
|
||||
storageNewReadP(storage, STRDEF(PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL)), .exactSize = PG_CONTROL_DATA_SIZE);
|
||||
|
||||
result = pgControlFromBuffer(controlFile);
|
||||
result = pgControlFromBuffer(controlFile, pgVersionForce);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
@ -267,10 +282,11 @@ typedef struct PgWalCommon
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
FN_EXTERN PgWal
|
||||
pgWalFromBuffer(const Buffer *walBuffer)
|
||||
pgWalFromBuffer(const Buffer *walBuffer, const String *const pgVersionForce)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelTrace);
|
||||
FUNCTION_LOG_PARAM(BUFFER, walBuffer);
|
||||
FUNCTION_LOG_PARAM(STRING, pgVersionForce);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(walBuffer != NULL);
|
||||
@ -282,26 +298,33 @@ pgWalFromBuffer(const Buffer *walBuffer)
|
||||
// Search for the version of PostgreSQL that uses this WAL magic
|
||||
const PgInterface *interface = NULL;
|
||||
|
||||
for (unsigned int interfaceIdx = 0; interfaceIdx < LENGTH_OF(pgInterface); interfaceIdx++)
|
||||
if (pgVersionForce != NULL)
|
||||
interface = pgInterfaceVersion(pgVersionFromStr(pgVersionForce));
|
||||
else
|
||||
{
|
||||
if (pgInterface[interfaceIdx].walIs(bufPtrConst(walBuffer)))
|
||||
for (unsigned int interfaceIdx = 0; interfaceIdx < LENGTH_OF(pgInterface); interfaceIdx++)
|
||||
{
|
||||
interface = &pgInterface[interfaceIdx];
|
||||
break;
|
||||
if (pgInterface[interfaceIdx].walIs(bufPtrConst(walBuffer)))
|
||||
{
|
||||
interface = &pgInterface[interfaceIdx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the version was not found then error with the magic that was found
|
||||
if (interface == NULL)
|
||||
{
|
||||
THROW_FMT(
|
||||
VersionNotSupportedError,
|
||||
"unexpected WAL magic %u\n"
|
||||
"HINT: is this version of PostgreSQL supported?",
|
||||
((const PgWalCommon *)bufPtrConst(walBuffer))->magic);
|
||||
}
|
||||
}
|
||||
|
||||
// If the version was not found then error with the magic that was found
|
||||
if (interface == NULL)
|
||||
{
|
||||
THROW_FMT(
|
||||
VersionNotSupportedError,
|
||||
"unexpected WAL magic %u\n"
|
||||
"HINT: is this version of PostgreSQL supported?",
|
||||
((const PgWalCommon *)bufPtrConst(walBuffer))->magic);
|
||||
}
|
||||
|
||||
// Get info from the control file
|
||||
ASSERT(pgVersionForce != NULL || interface->walIs(bufPtrConst(walBuffer)));
|
||||
|
||||
PgWal result = interface->wal(bufPtrConst(walBuffer));
|
||||
result.version = interface->version;
|
||||
|
||||
@ -312,10 +335,11 @@ pgWalFromBuffer(const Buffer *walBuffer)
|
||||
}
|
||||
|
||||
FN_EXTERN PgWal
|
||||
pgWalFromFile(const String *walFile, const Storage *storage)
|
||||
pgWalFromFile(const String *walFile, const Storage *storage, const String *const pgVersionForce)
|
||||
{
|
||||
FUNCTION_LOG_BEGIN(logLevelDebug);
|
||||
FUNCTION_LOG_PARAM(STRING, walFile);
|
||||
FUNCTION_LOG_PARAM(STRING, pgVersionForce);
|
||||
FUNCTION_LOG_END();
|
||||
|
||||
ASSERT(walFile != NULL);
|
||||
@ -327,7 +351,7 @@ pgWalFromFile(const String *walFile, const Storage *storage)
|
||||
// Read WAL segment header
|
||||
Buffer *walBuffer = storageGetP(storageNewReadP(storage, walFile), .exactSize = PG_WAL_HEADER_SIZE);
|
||||
|
||||
result = pgWalFromBuffer(walBuffer);
|
||||
result = pgWalFromBuffer(walBuffer, pgVersionForce);
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
|
@ -130,7 +130,7 @@ FN_EXTERN bool pgDbIsSystem(const String *name);
|
||||
FN_EXTERN bool pgDbIsSystemId(unsigned int id);
|
||||
|
||||
// Get info from pg_control
|
||||
FN_EXTERN PgControl pgControlFromFile(const Storage *storage);
|
||||
FN_EXTERN PgControl pgControlFromFile(const Storage *storage, const String *pgVersionForce);
|
||||
|
||||
// Get the control version for a PostgreSQL version
|
||||
FN_EXTERN uint32_t pgControlVersion(unsigned int pgVersion);
|
||||
@ -140,8 +140,8 @@ FN_EXTERN unsigned int pgVersionFromStr(const String *version);
|
||||
FN_EXTERN String *pgVersionToStr(unsigned int version);
|
||||
|
||||
// Get info from WAL header
|
||||
FN_EXTERN PgWal pgWalFromFile(const String *walFile, const Storage *storage);
|
||||
FN_EXTERN PgWal pgWalFromBuffer(const Buffer *walBuffer);
|
||||
FN_EXTERN PgWal pgWalFromFile(const String *walFile, const Storage *storage, const String *pgVersionForce);
|
||||
FN_EXTERN PgWal pgWalFromBuffer(const Buffer *walBuffer, const String *pgVersionForce);
|
||||
|
||||
// Get the tablespace identifier used to distinguish versions in a tablespace directory, e.g. PG_15_202209061
|
||||
FN_EXTERN String *pgTablespaceId(unsigned int pgVersion, unsigned int pgCatalogVersion);
|
||||
|
@ -61,7 +61,6 @@ Read the version specific pg_control into a general data structure
|
||||
pgInterfaceControl##version(const unsigned char *controlFile) \
|
||||
{ \
|
||||
ASSERT(controlFile != NULL); \
|
||||
ASSERT(pgInterfaceControlIs##version(controlFile)); \
|
||||
\
|
||||
return (PgControl) \
|
||||
{ \
|
||||
@ -123,7 +122,6 @@ Read the version specific WAL header into a general data structure
|
||||
pgInterfaceWal##version(const unsigned char *walFile) \
|
||||
{ \
|
||||
ASSERT(walFile != NULL); \
|
||||
ASSERT(pgInterfaceWalIs##version(walFile)); \
|
||||
\
|
||||
return (PgWal) \
|
||||
{ \
|
||||
|
Reference in New Issue
Block a user