2019-08-01 20:35:01 -04:00
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Test Check Command
|
|
|
|
***********************************************************************************************************************************/
|
2021-05-17 07:20:28 -04:00
|
|
|
#include "command/stanza/create.h"
|
|
|
|
#include "info/infoArchive.h"
|
|
|
|
#include "info/infoBackup.h"
|
2019-08-01 20:35:01 -04:00
|
|
|
#include "postgres/version.h"
|
|
|
|
#include "storage/helper.h"
|
2019-10-08 18:04:09 -04:00
|
|
|
#include "storage/posix/storage.h"
|
2019-08-01 20:35:01 -04:00
|
|
|
#include "storage/storage.intern.h"
|
|
|
|
|
|
|
|
#include "common/harnessConfig.h"
|
|
|
|
#include "common/harnessInfo.h"
|
2021-05-17 07:20:28 -04:00
|
|
|
#include "common/harnessPostgres.h"
|
2019-08-01 20:35:01 -04:00
|
|
|
#include "common/harnessPq.h"
|
|
|
|
|
|
|
|
/***********************************************************************************************************************************
|
|
|
|
Test Run
|
|
|
|
***********************************************************************************************************************************/
|
|
|
|
void
|
|
|
|
testRun(void)
|
|
|
|
{
|
|
|
|
FUNCTION_HARNESS_VOID();
|
|
|
|
|
2019-12-07 17:33:34 -05:00
|
|
|
// PQfinish() is strictly checked
|
|
|
|
harnessPqScriptStrictSet(true);
|
|
|
|
|
2020-04-30 11:01:38 -04:00
|
|
|
Storage *storageTest = storagePosixNewP(strNew(testPath()), .write = true);
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
String *pg1 = strNew("pg1");
|
2020-07-30 07:49:06 -04:00
|
|
|
String *pg1Path = strNewFmt("%s/%s", testPath(), strZ(pg1));
|
|
|
|
String *pg1PathOpt = strNewFmt("--pg1-path=%s", strZ(pg1Path));
|
2019-10-08 18:04:09 -04:00
|
|
|
String *pg8 = strNew("pg8");
|
2020-07-30 07:49:06 -04:00
|
|
|
String *pg8Path = strNewFmt("%s/%s", testPath(), strZ(pg8));
|
|
|
|
String *pg8PathOpt = strNewFmt("--pg8-path=%s", strZ(pg8Path));
|
2019-10-08 18:04:09 -04:00
|
|
|
String *stanza = strNew("test1");
|
2020-07-30 07:49:06 -04:00
|
|
|
String *stanzaOpt = strNewFmt("--stanza=%s", strZ(stanza));
|
2019-10-08 18:04:09 -04:00
|
|
|
StringList *argList = strLstNew();
|
2019-08-21 15:41:52 -04:00
|
|
|
|
2019-08-01 20:35:01 -04:00
|
|
|
// *****************************************************************************************************************************
|
|
|
|
if (testBegin("cmdCheck()"))
|
|
|
|
{
|
2019-10-08 18:04:09 -04:00
|
|
|
// Load Parameters
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
2019-08-21 15:41:52 -04:00
|
|
|
strLstAdd(argList, pg1PathOpt);
|
2019-08-01 20:35:01 -04:00
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
|
|
strLstAddZ(argList, "--archive-timeout=.5");
|
2019-10-08 12:06:30 -04:00
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
2019-08-01 20:35:01 -04:00
|
|
|
|
2019-10-08 18:04:09 -04:00
|
|
|
// Set up harness to expect a failure to connect to the database
|
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
|
|
|
{.function = HRNPQ_CONNECTDB, .param = "[\"dbname='postgres' port=5432\"]"},
|
|
|
|
{.function = HRNPQ_STATUS, .resultInt = CONNECTION_BAD},
|
|
|
|
{.function = HRNPQ_ERRORMESSAGE, .resultZ = "error"},
|
|
|
|
{.function = HRNPQ_FINISH},
|
|
|
|
{.function = NULL}
|
|
|
|
});
|
|
|
|
|
|
|
|
TEST_ERROR_FMT(cmdCheck(), ConfigError, "no database found\nHINT: check indexed pg-path/pg-host configurations");
|
|
|
|
harnessLogResult(
|
|
|
|
"P00 WARN: unable to check pg-1: [DbConnectError] unable to connect to 'dbname='postgres' port=5432': error");
|
|
|
|
|
|
|
|
// Standby only, repo local
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, strZ(pg1Path), true, NULL, NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
|
|
|
TEST_ERROR(cmdCheck(), ConfigError, "primary database not found\nHINT: check indexed pg-path/pg-host configurations");
|
|
|
|
|
2021-01-21 15:21:50 -05:00
|
|
|
// Standby only, one of multiple repos remote but more than one pg-path configured
|
2019-10-08 18:04:09 -04:00
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
|
|
|
strLstAdd(argList, pg1PathOpt);
|
|
|
|
strLstAddZ(argList, "--pg8-path=/path/to/standby2");
|
|
|
|
strLstAddZ(argList, "--pg8-port=5433");
|
2021-01-21 15:21:50 -05:00
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
|
|
strLstAddZ(argList, "--repo2-host=repo.domain.com");
|
2019-10-08 18:04:09 -04:00
|
|
|
strLstAddZ(argList, "--archive-timeout=.5");
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
|
|
|
|
|
|
|
// Two standbys found but no primary
|
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-06-24 18:40:19 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, "/pgdata", true, NULL, NULL),
|
|
|
|
HRNPQ_MACRO_OPEN_GE_92(8, "dbname='postgres' port=5433", PG_VERSION_92, "/pgdata", true, NULL, NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
HRNPQ_MACRO_CLOSE(8),
|
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
|
|
|
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
|
|
|
TEST_ERROR(cmdCheck(), ConfigError, "primary database not found\nHINT: check indexed pg-path/pg-host configurations");
|
|
|
|
|
|
|
|
// Standby only, repo remote but only one pg-path configured
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
|
|
|
strLstAdd(argList, pg1PathOpt);
|
|
|
|
strLstAddZ(argList, "--repo1-host=repo.domain.com");
|
|
|
|
strLstAddZ(argList, "--archive-timeout=.5");
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
|
|
|
|
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-06-24 18:40:19 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, "/pgdata", true, NULL, NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
|
|
|
// Only confirming we get passed the check for isRepoLocal || more than one pg-path configured
|
2020-07-30 07:49:06 -04:00
|
|
|
TEST_ERROR_FMT(cmdCheck(), FileMissingError, "unable to open missing file '%s/global/pg_control' for read", strZ(pg1Path));
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
// backup-standby set without standby
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
|
|
|
strLstAdd(argList, pg1PathOpt);
|
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
|
|
strLstAddZ(argList, "--archive-timeout=.5");
|
|
|
|
strLstAddZ(argList, "--backup-standby");
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
|
|
|
|
|
|
|
// Primary database connection ok
|
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, strZ(pg1Path), false, NULL, NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
|
|
|
TEST_ERROR_FMT(
|
|
|
|
cmdCheck(), FileMissingError, "unable to open missing file '%s' for read",
|
2020-07-30 07:49:06 -04:00
|
|
|
strZ(strNewFmt("%s/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, strZ(pg1Path))));
|
2019-10-08 18:04:09 -04:00
|
|
|
harnessLogResult(
|
2020-07-30 07:49:06 -04:00
|
|
|
strZ(strNewFmt("P00 WARN: option '%s' is enabled but standby is not properly configured",
|
2019-10-08 18:04:09 -04:00
|
|
|
cfgOptionName(cfgOptBackupStandby))));
|
|
|
|
|
|
|
|
// Standby and primary database
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
// Create pg_control for standby
|
2019-11-17 15:10:40 -05:00
|
|
|
storagePutP(
|
2020-07-30 07:49:06 -04:00
|
|
|
storageNewWriteP(storageTest, strNewFmt("%s/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, strZ(pg1))),
|
2021-05-17 07:20:28 -04:00
|
|
|
hrnPgControlToBuffer((PgControl){.version = PG_VERSION_92, .systemId = 6569239123849665679}));
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
|
|
|
strLstAdd(argList, pg1PathOpt);
|
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
|
|
strLstAddZ(argList, "--archive-timeout=.5");
|
|
|
|
strLstAdd(argList, pg8PathOpt);
|
|
|
|
strLstAddZ(argList, "--pg8-port=5433");
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
|
|
|
|
|
|
|
// Standby database path doesn't match pg_control
|
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-06-24 18:40:19 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, testPath(), true, NULL, NULL),
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(8, "dbname='postgres' port=5433", PG_VERSION_92, strZ(pg8Path), false, NULL, NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
HRNPQ_MACRO_CLOSE(8),
|
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
|
|
|
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
|
|
|
TEST_ERROR_FMT(
|
|
|
|
cmdCheck(), 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.",
|
2020-07-30 07:49:06 -04:00
|
|
|
strZ(pgVersionToStr(PG_VERSION_92)), testPath(), strZ(pgVersionToStr(PG_VERSION_92)), strZ(pg1Path), strZ(pg1Path));
|
2019-10-08 18:04:09 -04:00
|
|
|
|
2021-01-21 15:21:50 -05:00
|
|
|
// Standby
|
2019-10-08 18:04:09 -04:00
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
2021-01-21 15:21:50 -05:00
|
|
|
// Create pg_control for primary
|
|
|
|
storagePutP(
|
|
|
|
storageNewWriteP(storageTest, strNewFmt("%s/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, strZ(pg8))),
|
2021-05-17 07:20:28 -04:00
|
|
|
hrnPgControlToBuffer((PgControl){.version = PG_VERSION_92, .systemId = 6569239123849665679}));
|
2021-01-21 15:21:50 -05:00
|
|
|
|
|
|
|
// Create info files
|
|
|
|
const Buffer *archiveInfoContent = harnessInfoChecksum(
|
|
|
|
strNew(
|
|
|
|
"[db]\n"
|
|
|
|
"db-id=1\n"
|
|
|
|
"db-system-id=6569239123849665679\n"
|
|
|
|
"db-version=\"9.2\"\n"
|
|
|
|
"\n"
|
|
|
|
"[db:history]\n"
|
|
|
|
"1={\"db-id\":6569239123849665679,\"db-version\":\"9.2\"}\n"));
|
|
|
|
|
|
|
|
storagePutP(storageNewWriteP(storageRepoIdxWrite(0), INFO_ARCHIVE_PATH_FILE_STR), archiveInfoContent);
|
|
|
|
|
|
|
|
const Buffer *backupInfoContent = harnessInfoChecksum(
|
|
|
|
strNew(
|
|
|
|
"[db]\n"
|
|
|
|
"db-catalog-version=201608131\n"
|
|
|
|
"db-control-version=920\n"
|
|
|
|
"db-id=1\n"
|
|
|
|
"db-system-id=6569239123849665679\n"
|
|
|
|
"db-version=\"9.2\"\n"
|
|
|
|
"\n"
|
|
|
|
"[db:history]\n"
|
|
|
|
"1={\"db-catalog-version\":201608131,\"db-control-version\":920,\"db-system-id\":6569239123849665679,"
|
|
|
|
"\"db-version\":\"9.2\"}\n"));
|
|
|
|
storagePutP(storageNewWriteP(storageRepoIdxWrite(0), INFO_BACKUP_PATH_FILE_STR), backupInfoContent);
|
|
|
|
|
|
|
|
// Single repo config - error when checking archive mode setting on database
|
2019-10-08 18:04:09 -04:00
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, strZ(pg1Path), true, NULL, NULL),
|
2021-01-21 15:21:50 -05:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(8, "dbname='postgres' port=5433", PG_VERSION_92, strZ(pg8Path), false, "off", NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
2021-01-21 15:21:50 -05:00
|
|
|
HRNPQ_MACRO_CLOSE(8),
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
2021-01-21 15:21:50 -05:00
|
|
|
// Error on primary but standby check ok
|
|
|
|
TEST_ERROR_FMT(cmdCheck(), ArchiveDisabledError, "archive_mode must be enabled");
|
|
|
|
harnessLogResult(
|
|
|
|
"P00 INFO: check repo1 (standby)\n"
|
|
|
|
"P00 INFO: switch wal not performed because this is a standby");
|
2019-08-01 20:35:01 -04:00
|
|
|
|
2021-01-21 15:21:50 -05:00
|
|
|
// Multi-repo - add a second repo (repo2)
|
|
|
|
StringList *argListRepo2 = strLstDup(argList);
|
|
|
|
strLstAdd(argListRepo2, strNewFmt("--repo2-path=%s/repo2", testPath()));
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argListRepo2);
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, strZ(pg1Path), true, NULL, NULL),
|
2021-01-21 15:21:50 -05:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(8, "dbname='postgres' port=5433", PG_VERSION_92, strZ(pg8Path), false, NULL, NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
HRNPQ_MACRO_CLOSE(8),
|
2021-01-21 15:21:50 -05:00
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
2021-01-21 15:21:50 -05:00
|
|
|
// Stanza has not yet been created on repo2 but is created (and checked) on repo1
|
|
|
|
TEST_ERROR_FMT(
|
|
|
|
cmdCheck(), FileMissingError,
|
|
|
|
"unable to load info file '%s/repo2/archive/test1/archive.info' or '%s/repo2/archive/test1/archive.info.copy':\n"
|
|
|
|
"FileMissingError: " STORAGE_ERROR_READ_MISSING "\n"
|
|
|
|
"FileMissingError: " STORAGE_ERROR_READ_MISSING "\n"
|
|
|
|
"HINT: archive.info cannot be opened but is required to push/get WAL segments.\n"
|
|
|
|
"HINT: is archive_command configured correctly in postgresql.conf?\n"
|
|
|
|
"HINT: has a stanza-create been performed?\n"
|
|
|
|
"HINT: use --no-archive-check to disable archive checks during backup if you have an alternate archiving scheme.",
|
|
|
|
testPath(), testPath(), strZ(strNewFmt("%s/repo2/archive/test1/archive.info", testPath())),
|
|
|
|
strZ(strNewFmt("%s/repo2/archive/test1/archive.info.copy", testPath())));
|
|
|
|
harnessLogResult("P00 INFO: check repo1 (standby)\nP00 INFO: check repo2 (standby)");
|
2019-10-08 18:04:09 -04:00
|
|
|
|
2019-08-01 20:35:01 -04:00
|
|
|
// Single primary
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
2021-01-21 15:21:50 -05:00
|
|
|
// Multi repo
|
2019-10-08 18:04:09 -04:00
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
|
|
|
strLstAdd(argList, pg1PathOpt);
|
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
2021-01-21 15:21:50 -05:00
|
|
|
strLstAdd(argList, strNewFmt("--repo2-path=%s/repo2", testPath()));
|
2019-10-08 18:04:09 -04:00
|
|
|
strLstAddZ(argList, "--archive-timeout=.5");
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
|
|
|
|
2021-01-21 15:21:50 -05:00
|
|
|
// Create stanza files on repo2
|
|
|
|
storagePutP(storageNewWriteP(storageRepoIdxWrite(1), INFO_ARCHIVE_PATH_FILE_STR), archiveInfoContent);
|
|
|
|
storagePutP(storageNewWriteP(storageRepoIdxWrite(1), INFO_BACKUP_PATH_FILE_STR), backupInfoContent);
|
|
|
|
|
2019-08-01 20:35:01 -04:00
|
|
|
// Error when WAL segment not found
|
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, strZ(pg1Path), false, NULL, NULL),
|
2019-08-01 20:35:01 -04:00
|
|
|
HRNPQ_MACRO_CREATE_RESTORE_POINT(1, "1/1"),
|
|
|
|
HRNPQ_MACRO_WAL_SWITCH(1, "xlog", "000000010000000100000001"),
|
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
|
|
|
TEST_ERROR(
|
|
|
|
cmdCheck(), ArchiveTimeoutError,
|
|
|
|
"WAL segment 000000010000000100000001 was not archived before the 500ms timeout\n"
|
2019-09-14 12:21:08 -04:00
|
|
|
"HINT: check the archive_command to ensure that all options are correct (especially --stanza).\n"
|
2020-09-03 07:49:49 -04:00
|
|
|
"HINT: check the PostgreSQL server log for errors.\n"
|
|
|
|
"HINT: run the 'start' command if the stanza was previously stopped.");
|
2021-01-21 15:21:50 -05:00
|
|
|
harnessLogResult(
|
|
|
|
"P00 INFO: check repo1 configuration (primary)\n"
|
|
|
|
"P00 INFO: check repo2 configuration (primary)\n"
|
|
|
|
"P00 INFO: check repo1 archive for WAL (primary)");
|
2019-08-01 20:35:01 -04:00
|
|
|
|
|
|
|
// Create WAL segment
|
|
|
|
Buffer *buffer = bufNew(16 * 1024 * 1024);
|
|
|
|
memset(bufPtr(buffer), 0, bufSize(buffer));
|
|
|
|
bufUsedSet(buffer, bufSize(buffer));
|
|
|
|
|
2021-01-21 15:21:50 -05:00
|
|
|
// WAL segment switch is performed once for all repos
|
2019-08-01 20:35:01 -04:00
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, strZ(pg1Path), false, NULL, NULL),
|
2019-08-01 20:35:01 -04:00
|
|
|
HRNPQ_MACRO_CREATE_RESTORE_POINT(1, "1/1"),
|
|
|
|
HRNPQ_MACRO_WAL_SWITCH(1, "xlog", "000000010000000100000001"),
|
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
2019-11-17 15:10:40 -05:00
|
|
|
storagePutP(
|
|
|
|
storageNewWriteP(
|
2021-01-21 15:21:50 -05:00
|
|
|
storageRepoIdxWrite(0),
|
|
|
|
strNew(STORAGE_REPO_ARCHIVE "/9.2-1/000000010000000100000001-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
|
|
|
|
buffer);
|
|
|
|
|
|
|
|
storagePutP(
|
|
|
|
storageNewWriteP(
|
|
|
|
storageRepoIdxWrite(1),
|
2019-08-01 20:35:01 -04:00
|
|
|
strNew(STORAGE_REPO_ARCHIVE "/9.2-1/000000010000000100000001-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")),
|
|
|
|
buffer);
|
|
|
|
|
2019-10-08 18:04:09 -04:00
|
|
|
TEST_RESULT_VOID(cmdCheck(), "check primary, WAL archived");
|
2019-08-01 20:35:01 -04:00
|
|
|
harnessLogResult(
|
2020-07-30 07:49:06 -04:00
|
|
|
strZ(
|
2019-08-01 20:35:01 -04:00
|
|
|
strNewFmt(
|
2021-01-21 15:21:50 -05:00
|
|
|
"P00 INFO: check repo1 configuration (primary)\n"
|
|
|
|
"P00 INFO: check repo2 configuration (primary)\n"
|
|
|
|
"P00 INFO: check repo1 archive for WAL (primary)\n"
|
2019-08-01 20:35:01 -04:00
|
|
|
"P00 INFO: WAL segment 000000010000000100000001 successfully archived to '%s/repo/archive/test1/9.2-1/"
|
2021-01-21 15:21:50 -05:00
|
|
|
"0000000100000001/000000010000000100000001-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' on repo1\n"
|
|
|
|
"P00 INFO: check repo2 archive for WAL (primary)\n"
|
|
|
|
"P00 INFO: WAL segment 000000010000000100000001 successfully archived to '%s/repo2/archive/test1/9.2-1/"
|
|
|
|
"0000000100000001/000000010000000100000001-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' on repo2",
|
|
|
|
testPath(), testPath())));
|
2019-08-01 20:35:01 -04:00
|
|
|
|
2019-10-08 18:04:09 -04:00
|
|
|
// Primary == NULL (for test coverage)
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
DbGetResult dbGroup = {0};
|
|
|
|
TEST_RESULT_VOID(checkPrimary(dbGroup), "primary == NULL");
|
|
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************************************************************
|
|
|
|
if (testBegin("checkManifest()"))
|
|
|
|
{
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
|
|
|
strLstAdd(argList, pg1PathOpt);
|
2020-10-19 14:03:48 -04:00
|
|
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHost, 5, "localhost");
|
|
|
|
hrnCfgArgKeyRawZ(argList, cfgOptPgHostCmd, 5, "pgbackrest-bogus");
|
2019-10-08 18:04:09 -04:00
|
|
|
strLstAddZ(argList, "--pg5-path=/path/to/pg5");
|
|
|
|
strLstAdd(argList, strNewFmt("--pg5-host-user=%s", testUser()));
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
|
|
|
|
|
|
|
// Placeholder test for manifest
|
|
|
|
TEST_ERROR(
|
|
|
|
checkManifest(), UnknownError,
|
2020-03-15 09:59:22 -04:00
|
|
|
"remote-0 process on 'localhost' terminated unexpectedly [127]: bash: pgbackrest-bogus: command not found");
|
2019-10-08 18:04:09 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// *****************************************************************************************************************************
|
|
|
|
if (testBegin("checkDbConfig(), checkArchiveCommand()"))
|
|
|
|
{
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
TEST_ERROR_FMT(
|
|
|
|
checkArchiveCommand(NULL), ArchiveCommandInvalidError, "archive_command '[null]' must contain " PROJECT_BIN);
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
TEST_ERROR_FMT(
|
|
|
|
checkArchiveCommand(strNew("")), ArchiveCommandInvalidError, "archive_command '' must contain " PROJECT_BIN);
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
TEST_ERROR_FMT(
|
|
|
|
checkArchiveCommand(strNew("backrest")), ArchiveCommandInvalidError, "archive_command 'backrest' must contain "
|
|
|
|
PROJECT_BIN);
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
TEST_RESULT_BOOL(checkArchiveCommand(strNew("pgbackrest --stanza=demo archive-push %p")), true, "archive_command valid");
|
|
|
|
|
2019-08-01 20:35:01 -04:00
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
argList = strLstNew();
|
2019-10-08 18:04:09 -04:00
|
|
|
strLstAdd(argList, stanzaOpt);
|
2019-08-21 15:41:52 -04:00
|
|
|
strLstAdd(argList, pg1PathOpt);
|
2019-10-08 18:04:09 -04:00
|
|
|
strLstAdd(argList, pg8PathOpt);
|
|
|
|
strLstAddZ(argList, "--pg8-port=5433");
|
2019-08-01 20:35:01 -04:00
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
2019-10-08 12:06:30 -04:00
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
2019-08-01 20:35:01 -04:00
|
|
|
|
2019-10-08 18:04:09 -04:00
|
|
|
DbGetResult db = {0};
|
|
|
|
|
2019-08-01 20:35:01 -04:00
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, strZ(pg1Path), false, NULL, NULL),
|
2020-06-24 18:40:19 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(8, "dbname='postgres' port=5433", PG_VERSION_92, "/badpath", true, NULL, NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
|
2019-08-01 20:35:01 -04:00
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
2019-10-08 18:04:09 -04:00
|
|
|
HRNPQ_MACRO_CLOSE(8),
|
2019-08-01 20:35:01 -04:00
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
2019-12-02 07:39:42 -05:00
|
|
|
TEST_ASSIGN(db, dbGet(false, false, false), "get primary and standby");
|
2019-08-01 20:35:01 -04:00
|
|
|
|
2020-10-26 10:25:16 -04:00
|
|
|
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config");
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
// Version mismatch
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
TEST_ERROR_FMT(
|
2020-10-26 10:25:16 -04:00
|
|
|
checkDbConfig(PG_VERSION_94, db.primaryIdx, db.primary, false), DbMismatchError,
|
2019-10-08 18:04:09 -04:00
|
|
|
"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.",
|
2020-07-30 07:49:06 -04:00
|
|
|
strZ(pgVersionToStr(PG_VERSION_92)), strZ(pg1Path), strZ(pgVersionToStr(PG_VERSION_94)), strZ(pg1Path), strZ(pg1Path));
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
// Path mismatch
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
TEST_ERROR_FMT(
|
2020-10-26 10:25:16 -04:00
|
|
|
checkDbConfig(PG_VERSION_92, db.standbyIdx, db.standby, true), DbMismatchError,
|
2019-10-08 18:04:09 -04:00
|
|
|
"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 pg8-path and pg8-port settings likely reference different clusters.",
|
2020-07-30 07:49:06 -04:00
|
|
|
strZ(pgVersionToStr(PG_VERSION_92)), strZ(dbPgDataPath(db.standby)), strZ(pgVersionToStr(PG_VERSION_92)), strZ(pg8Path),
|
|
|
|
strZ(pg8Path));
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
// archive-check=false
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
strLstAddZ(argList, "--no-archive-check");
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
|
|
|
|
2020-10-26 10:25:16 -04:00
|
|
|
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config --no-archive-check");
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
// archive-check not valid for command
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
|
|
|
strLstAdd(argList, pg1PathOpt);
|
|
|
|
strLstAdd(argList, pg8PathOpt);
|
|
|
|
strLstAddZ(argList, "--pg8-port=5433");
|
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
|
|
harnessCfgLoad(cfgCmdStanzaCreate, argList);
|
|
|
|
|
|
|
|
TEST_RESULT_VOID(
|
2020-10-26 10:25:16 -04:00
|
|
|
checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config, archive-check not valid for command");
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
TEST_RESULT_VOID(dbFree(db.primary), "free primary");
|
|
|
|
TEST_RESULT_VOID(dbFree(db.standby), "free standby");
|
|
|
|
|
|
|
|
// archive_mode=always not supported
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
2019-08-21 15:41:52 -04:00
|
|
|
strLstAdd(argList, pg1PathOpt);
|
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
2019-10-08 12:06:30 -04:00
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
2019-08-21 15:41:52 -04:00
|
|
|
|
2019-10-08 18:04:09 -04:00
|
|
|
harnessPqScriptSet((HarnessPq [])
|
|
|
|
{
|
2020-07-30 07:49:06 -04:00
|
|
|
HRNPQ_MACRO_OPEN_GE_92(1, "dbname='postgres' port=5432", PG_VERSION_92, strZ(pg1Path), false, "always", NULL),
|
2019-10-08 18:04:09 -04:00
|
|
|
HRNPQ_MACRO_CLOSE(1),
|
|
|
|
HRNPQ_MACRO_DONE()
|
|
|
|
});
|
|
|
|
|
2019-12-02 07:39:42 -05:00
|
|
|
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
|
2019-10-08 18:04:09 -04:00
|
|
|
TEST_ERROR_FMT(
|
2020-10-26 10:25:16 -04:00
|
|
|
checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), FeatureNotSupportedError,
|
2019-10-08 18:04:09 -04:00
|
|
|
"archive_mode=always not supported");
|
|
|
|
|
2021-02-02 19:43:14 +01:00
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
TEST_TITLE("disable archive_mode=always check");
|
|
|
|
|
|
|
|
strLstAddZ(argList, "--no-archive-mode-check");
|
|
|
|
harnessCfgLoad(cfgCmdCheck, argList);
|
|
|
|
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "check");
|
|
|
|
|
2019-10-08 18:04:09 -04:00
|
|
|
TEST_RESULT_VOID(dbFree(db.primary), "free primary");
|
|
|
|
}
|
2019-08-21 15:41:52 -04:00
|
|
|
|
2019-10-08 18:04:09 -04:00
|
|
|
// *****************************************************************************************************************************
|
|
|
|
if (testBegin("checkStanzaInfo(), checkStanzaInfoPg()"))
|
|
|
|
{
|
|
|
|
InfoArchive *archiveInfo = infoArchiveNew(PG_VERSION_96, 6569239123849665679, NULL);
|
|
|
|
InfoPgData archivePg = infoPgData(infoArchivePg(archiveInfo), infoPgDataCurrentId(infoArchivePg(archiveInfo)));
|
|
|
|
|
2021-05-17 07:20:28 -04:00
|
|
|
InfoBackup *backupInfo = infoBackupNew(PG_VERSION_96, 6569239123849665679, hrnPgCatalogVersion(PG_VERSION_96), NULL);
|
2019-10-08 18:04:09 -04:00
|
|
|
InfoPgData backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
|
|
|
|
|
|
|
|
TEST_RESULT_VOID(checkStanzaInfo(&archivePg, &backupPg), "stanza info files match");
|
|
|
|
|
|
|
|
// Create a corrupted backup file - system id
|
2019-08-21 15:41:52 -04:00
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
2021-05-17 07:20:28 -04:00
|
|
|
backupInfo = infoBackupNew(PG_VERSION_96, 6569239123849665999, hrnPgCatalogVersion(PG_VERSION_96), NULL);
|
2019-10-08 18:04:09 -04:00
|
|
|
backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
|
|
|
|
|
2019-08-21 15:41:52 -04:00
|
|
|
TEST_ERROR_FMT(
|
2019-10-08 18:04:09 -04:00
|
|
|
checkStanzaInfo(&archivePg, &backupPg), FileInvalidError, "backup info file and archive info file do not match\n"
|
|
|
|
"archive: id = 1, version = 9.6, system-id = 6569239123849665679\n"
|
|
|
|
"backup : id = 1, version = 9.6, system-id = 6569239123849665999\n"
|
|
|
|
"HINT: this may be a symptom of repository corruption!");
|
2019-08-21 15:41:52 -04:00
|
|
|
|
2019-10-08 18:04:09 -04:00
|
|
|
// Create a corrupted backup file - system id and version
|
2019-08-21 15:41:52 -04:00
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
2021-05-17 07:20:28 -04:00
|
|
|
backupInfo = infoBackupNew(PG_VERSION_95, 6569239123849665999, hrnPgCatalogVersion(PG_VERSION_95), NULL);
|
2019-10-08 18:04:09 -04:00
|
|
|
backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
|
|
|
|
|
2019-08-21 15:41:52 -04:00
|
|
|
TEST_ERROR_FMT(
|
2019-10-08 18:04:09 -04:00
|
|
|
checkStanzaInfo(&archivePg, &backupPg), FileInvalidError, "backup info file and archive info file do not match\n"
|
|
|
|
"archive: id = 1, version = 9.6, system-id = 6569239123849665679\n"
|
|
|
|
"backup : id = 1, version = 9.5, system-id = 6569239123849665999\n"
|
|
|
|
"HINT: this may be a symptom of repository corruption!");
|
|
|
|
|
|
|
|
// Create a corrupted backup file - version
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
2021-05-17 07:20:28 -04:00
|
|
|
backupInfo = infoBackupNew(PG_VERSION_95, 6569239123849665679, hrnPgCatalogVersion(PG_VERSION_95), NULL);
|
2019-10-08 18:04:09 -04:00
|
|
|
backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
|
|
|
|
|
|
|
|
TEST_ERROR_FMT(
|
|
|
|
checkStanzaInfo(&archivePg, &backupPg), FileInvalidError, "backup info file and archive info file do not match\n"
|
|
|
|
"archive: id = 1, version = 9.6, system-id = 6569239123849665679\n"
|
|
|
|
"backup : id = 1, version = 9.5, system-id = 6569239123849665679\n"
|
|
|
|
"HINT: this may be a symptom of repository corruption!");
|
|
|
|
|
|
|
|
// Create a corrupted backup file - db id
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
2021-05-17 07:20:28 -04:00
|
|
|
infoBackupPgSet(backupInfo, PG_VERSION_96, 6569239123849665679, hrnPgCatalogVersion(PG_VERSION_96));
|
2019-10-08 18:04:09 -04:00
|
|
|
backupPg = infoPgData(infoBackupPg(backupInfo), infoPgDataCurrentId(infoBackupPg(backupInfo)));
|
|
|
|
|
|
|
|
TEST_ERROR_FMT(
|
|
|
|
checkStanzaInfo(&archivePg, &backupPg), FileInvalidError, "backup info file and archive info file do not match\n"
|
|
|
|
"archive: id = 1, version = 9.6, system-id = 6569239123849665679\n"
|
|
|
|
"backup : id = 2, version = 9.6, system-id = 6569239123849665679\n"
|
|
|
|
"HINT: this may be a symptom of repository corruption!");
|
|
|
|
|
|
|
|
// checkStanzaInfoPg
|
|
|
|
// -------------------------------------------------------------------------------------------------------------------------
|
|
|
|
argList = strLstNew();
|
|
|
|
strLstAddZ(argList, "--no-online");
|
|
|
|
strLstAdd(argList, stanzaOpt);
|
2020-07-30 07:49:06 -04:00
|
|
|
strLstAdd(argList, strNewFmt("--pg1-path=%s/%s", testPath(), strZ(stanza)));
|
2019-10-08 18:04:09 -04:00
|
|
|
strLstAdd(argList, strNewFmt("--repo1-path=%s/repo", testPath()));
|
|
|
|
strLstAddZ(argList, "--repo1-cipher-type=aes-256-cbc");
|
|
|
|
setenv("PGBACKREST_REPO1_CIPHER_PASS", "12345678", true);
|
|
|
|
harnessCfgLoad(cfgCmdStanzaCreate, argList);
|
|
|
|
|
|
|
|
// Create pg_control
|
2019-11-17 15:10:40 -05:00
|
|
|
storagePutP(
|
2020-07-30 07:49:06 -04:00
|
|
|
storageNewWriteP(storageTest, strNewFmt("%s/" PG_PATH_GLOBAL "/" PG_FILE_PGCONTROL, strZ(stanza))),
|
2021-05-17 07:20:28 -04:00
|
|
|
hrnPgControlToBuffer((PgControl){.version = PG_VERSION_96, .systemId = 6569239123849665679}));
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
// Create info files
|
|
|
|
TEST_RESULT_VOID(cmdStanzaCreate(), "stanza create - encryption");
|
2021-01-21 15:21:50 -05:00
|
|
|
harnessLogResult("P00 INFO: stanza-create for stanza 'test1' on repo1");
|
2019-10-08 18:04:09 -04:00
|
|
|
|
|
|
|
// Version mismatch
|
|
|
|
TEST_ERROR_FMT(
|
2021-01-21 15:21:50 -05:00
|
|
|
checkStanzaInfoPg(
|
2021-04-28 11:36:20 -04:00
|
|
|
storageRepoIdx(0), PG_VERSION_94, 6569239123849665679, cfgOptionIdxStrId(cfgOptRepoCipherType, 0),
|
2021-01-21 15:21:50 -05:00
|
|
|
cfgOptionIdxStr(cfgOptRepoCipherPass, 0)),
|
|
|
|
FileInvalidError,
|
2019-10-08 18:04:09 -04:00
|
|
|
"backup and archive info files exist but do not match the database\n"
|
|
|
|
"HINT: is this the correct stanza?\n"
|
|
|
|
"HINT: did an error occur during stanza-upgrade?");
|
|
|
|
|
|
|
|
// SystemId mismatch
|
|
|
|
TEST_ERROR_FMT(
|
2021-01-21 15:21:50 -05:00
|
|
|
checkStanzaInfoPg(
|
2021-04-28 11:36:20 -04:00
|
|
|
storageRepoIdx(0), PG_VERSION_96, 6569239123849665699, cfgOptionIdxStrId(cfgOptRepoCipherType, 0),
|
2021-01-21 15:21:50 -05:00
|
|
|
cfgOptionIdxStr(cfgOptRepoCipherPass, 0)),
|
|
|
|
FileInvalidError,
|
2019-10-08 18:04:09 -04:00
|
|
|
"backup and archive info files exist but do not match the database\n"
|
|
|
|
"HINT: is this the correct stanza?\n"
|
|
|
|
"HINT: did an error occur during stanza-upgrade?");
|
2019-08-21 15:41:52 -04:00
|
|
|
}
|
|
|
|
|
2021-03-10 18:42:22 -05:00
|
|
|
FUNCTION_HARNESS_RETURN_VOID();
|
2019-08-01 20:35:01 -04:00
|
|
|
}
|