1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-03-03 14:52:21 +02:00

Add checkDbConfig() to compare pgBackRest/PostgreSQL configs.

Checking the PostgreSQL-reported path and version against the pgBackRest configuration helps ensure that pgBackRest is operating against the correct cluster.

In Perl this functionality was in the Db object, but check seems like a better place for it in C.

Contributed by Cynthia Shang.
This commit is contained in:
Cynthia Shang 2019-08-21 15:41:52 -04:00 committed by David Steele
parent 8b93fdf349
commit 53f27da3a6
5 changed files with 98 additions and 5 deletions

View File

@ -55,6 +55,7 @@ SRCS = \
command/backup/file.c \
command/backup/pageChecksum.c \
command/check/check.c \
command/check/common.c \
command/backup/protocol.c \
command/expire/expire.c \
command/help/help.c \
@ -241,6 +242,9 @@ command/backup/protocol.o: command/backup/protocol.c build.auto.h command/backup
command/check/check.o: command/check/check.c build.auto.h command/archive/common.h command/check/check.h common/assert.h common/crypto/common.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h db/db.h db/helper.h info/info.h info/infoArchive.h info/infoPg.h postgres/client.h protocol/client.h protocol/command.h storage/helper.h storage/info.h storage/read.h storage/storage.h storage/write.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c command/check/check.c -o command/check/check.o
command/check/common.o: command/check/common.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h db/db.h db/helper.h postgres/client.h postgres/interface.h protocol/client.h protocol/command.h storage/info.h storage/read.h storage/storage.h storage/write.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c command/check/common.c -o command/check/common.o
command/command.o: command/command.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/http/client.h common/io/http/header.h common/io/http/query.h common/io/read.h common/io/tls/client.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h version.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c command/command.c -o command/command.o

View File

@ -0,0 +1,41 @@
/***********************************************************************************************************************************
Check Common Handler
***********************************************************************************************************************************/
#include "build.auto.h"
#include "common/debug.h"
#include "config/config.h"
#include "db/db.h"
#include "db/helper.h"
#include "postgres/interface.h"
/***********************************************************************************************************************************
Check the database path and version are configured correctly
***********************************************************************************************************************************/
void
checkDbConfig(const unsigned int pgVersion, const unsigned int dbIdx, const unsigned int dbVersion, const String *dbPath)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, pgVersion);
FUNCTION_TEST_PARAM(UINT, dbIdx);
FUNCTION_TEST_PARAM(UINT, dbVersion);
FUNCTION_TEST_PARAM(STRING, dbPath);
FUNCTION_TEST_END();
ASSERT(dbIdx > 0);
ASSERT(dbPath != NULL);
unsigned int pgPath = cfgOptPgPath + (dbIdx - 1);
// Error if the version from the control file and the configured pg-path do not match the values obtained from the database
if (pgVersion != dbVersion || strCmp(cfgOptionStr(pgPath), dbPath) != 0)
{
THROW_FMT(
DbMismatchError, "version '%s' and path '%s' queried from cluster do not match version '%s' and '%s' read from '%s/"
PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "'\nHINT: the %s and %s settings likely reference different clusters",
strPtr(pgVersionToStr(dbVersion)), strPtr(dbPath), strPtr(pgVersionToStr(pgVersion)), strPtr(cfgOptionStr(pgPath)),
strPtr(cfgOptionStr(pgPath)), cfgOptionName(pgPath), cfgOptionName(cfgOptPgPort + (dbIdx - 1)));
}
FUNCTION_TEST_RETURN_VOID();
}

View File

@ -0,0 +1,14 @@
/***********************************************************************************************************************************
Check Command Common
***********************************************************************************************************************************/
#ifndef COMMAND_CHECK_COMMON_H
#define COMMAND_CHECK_COMMON_H
#include "common/type/string.h"
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void checkDbConfig(const unsigned int pgVersion, const unsigned int dbIdx, const unsigned int dbVersion, const String *dbPath);
#endif

View File

@ -620,9 +620,10 @@ unit:
# ----------------------------------------------------------------------------------------------------------------------------
- name: check
total: 1
total: 2
coverage:
command/check/common: full
command/check/check: full
# ----------------------------------------------------------------------------------------------------------------------------

View File

@ -17,15 +17,16 @@ testRun(void)
{
FUNCTION_HARNESS_VOID();
String *pg1Path = strNewFmt("%s/pg1", testPath());
String *pg1PathOpt = strNewFmt("--pg1-path=%s", strPtr(pg1Path));
// *****************************************************************************************************************************
if (testBegin("cmdCheck()"))
{
String *pg1Path = strNewFmt("--pg1-path=%s/pg1", testPath());
StringList *argList = strLstNew();
strLstAddZ(argList, "pgbackrest");
strLstAddZ(argList, "--stanza=test1");
strLstAdd(argList, pg1Path);
strLstAdd(argList, pg1PathOpt);
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
strLstAddZ(argList, "--archive-timeout=.5");
strLstAddZ(argList, "check");
@ -108,7 +109,7 @@ testRun(void)
argList = strLstNew();
strLstAddZ(argList, "pgbackrest");
strLstAddZ(argList, "--stanza=test1");
strLstAdd(argList, pg1Path);
strLstAdd(argList, pg1PathOpt);
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
strLstAddZ(argList, "--archive-timeout=.5");
strLstAddZ(argList, "check");
@ -126,5 +127,37 @@ testRun(void)
harnessLogResult("P00 INFO: switch wal not performed because no primary was found");
}
// *****************************************************************************************************************************
if (testBegin("checkDbConfig()"))
{
StringList *argList = strLstNew();
strLstAddZ(argList, "pgbackrest");
strLstAddZ(argList, "--stanza=test1");
strLstAdd(argList, pg1PathOpt);
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
strLstAddZ(argList, "check");
harnessCfgLoad(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, 1, PG_VERSION_92, pg1Path), "valid db config");
// -------------------------------------------------------------------------------------------------------------------------
TEST_ERROR_FMT(
checkDbConfig(PG_VERSION_92, 1, PG_VERSION_94, pg1Path),
DbMismatchError, "version '%s' and path '%s' queried from cluster do not match version '%s' and '%s'"
" read from '%s/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "'\n"
"HINT: the pg1-path and pg1-port settings likely reference different clusters",
strPtr(pgVersionToStr(PG_VERSION_94)), strPtr(pg1Path), strPtr(pgVersionToStr(PG_VERSION_92)), strPtr(pg1Path),
strPtr(pg1Path));
// -------------------------------------------------------------------------------------------------------------------------
TEST_ERROR_FMT(
checkDbConfig(PG_VERSION_92, 1, PG_VERSION_92, strNew("bogus/path")),
DbMismatchError, "version '%s' and path '%s' queried from cluster do not match version '%s' and '%s'"
" read from '%s/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL "'\n"
"HINT: the pg1-path and pg1-port settings likely reference different clusters",
strPtr(pgVersionToStr(PG_VERSION_92)), "bogus/path", strPtr(pgVersionToStr(PG_VERSION_92)), strPtr(pg1Path),
strPtr(pg1Path));
}
FUNCTION_HARNESS_RESULT_VOID();
}