1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-17 01:12:23 +02:00

Use zero-based indexes when referring to option indexes.

There were a number of places in the code where "hostId" was used, but hostId is just the option group index + 1 so this led to a lot of +1 and -1 to convert the id to an index and vice versa.

Instead just use the zero based index wherever possible. This is pretty much everywhere except when the host-id option is read or set, or where a message is being formatted for the user.

Also fix a bug in protocolRemoteParam() where remotes spawned from the main process could get process ids that were not 0. Only the locals should spawn remotes with process id > 0. This seems to have been harmless since the process id is only a label, but it could be confusing when debugging.
This commit is contained in:
David Steele
2020-10-26 10:25:16 -04:00
committed by GitHub
parent ae35c4f029
commit d452e9cc38
21 changed files with 169 additions and 182 deletions

View File

@ -58,6 +58,14 @@
<p>Add option groups.</p>
</release-item>
<release-item>
<release-item-contributor-list>
<release-item-reviewer id="cynthia.shang"/>
</release-item-contributor-list>
<p>Use zero-based indexes when referring to option indexes.</p>
</release-item>
<release-item>
<release-item-contributor-list>
<release-item-reviewer id="stephen.frost"/>

View File

@ -339,7 +339,7 @@ cmdArchiveGetAsync(void)
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, archiveGetAsyncCallback, &jobData);
for (unsigned int processIdx = 1; processIdx <= cfgOptionUInt(cfgOptProcessMax); processIdx++)
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 1, processIdx));
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 0, processIdx));
// Process jobs
do

View File

@ -504,7 +504,7 @@ cmdArchivePushAsync(void)
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, archivePushAsyncCallback, &jobData);
for (unsigned int processIdx = 1; processIdx <= cfgOptionUInt(cfgOptProcessMax); processIdx++)
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 1, processIdx));
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 0, processIdx));
// Process jobs
do

View File

@ -175,12 +175,12 @@ Get the postgres database and storage objects
typedef struct BackupData
{
unsigned int pgIdPrimary; // Configuration id of the primary
unsigned int pgIdxPrimary; // cfgOptGrpPg index of the primary
Db *dbPrimary; // Database connection to the primary
const Storage *storagePrimary; // Storage object for the primary
const String *hostPrimary; // Host name of the primary
unsigned int pgIdStandby; // Configuration id of the standby
unsigned int pgIdxStandby; // cfgOptGrpPg index of the standby
Db *dbStandby; // Database connection to the standby
const Storage *storageStandby; // Storage object for the standby
const String *hostStandby; // Host name of the standby
@ -200,7 +200,7 @@ backupInit(const InfoBackup *infoBackup)
// Initialize for offline backup
BackupData *result = memNew(sizeof(BackupData));
*result = (BackupData){.pgIdPrimary = 1};
*result = (BackupData){0};
// Check that the PostgreSQL version supports backup from standby. The check is done using the stanza info because pg_control
// cannot be loaded until a primary is found -- which will also lead to an error if the version does not support standby. If the
@ -228,23 +228,23 @@ backupInit(const InfoBackup *infoBackup)
bool backupStandby = cfgOptionBool(cfgOptBackupStandby);
DbGetResult dbInfo = dbGet(!backupStandby, true, backupStandby);
result->pgIdPrimary = dbInfo.primaryId;
result->pgIdxPrimary = dbInfo.primaryIdx;
result->dbPrimary = dbInfo.primary;
if (backupStandby)
{
ASSERT(dbInfo.standbyId != 0);
ASSERT(dbInfo.standby != NULL);
result->pgIdStandby = dbInfo.standbyId;
result->pgIdxStandby = dbInfo.standbyIdx;
result->dbStandby = dbInfo.standby;
result->storageStandby = storagePgId(result->pgIdStandby);
result->hostStandby = cfgOptionStrNull(cfgOptPgHost + result->pgIdStandby - 1);
result->storageStandby = storagePgIdx(result->pgIdxStandby);
result->hostStandby = cfgOptionStrNull(cfgOptPgHost + result->pgIdxStandby);
}
}
// Add primary info
result->storagePrimary = storagePgId(result->pgIdPrimary);
result->hostPrimary = cfgOptionStrNull(cfgOptPgHost + result->pgIdPrimary - 1);
result->storagePrimary = storagePgIdx(result->pgIdxPrimary);
result->hostPrimary = cfgOptionStrNull(cfgOptPgHost + result->pgIdxPrimary);
// Get pg_control info from the primary
PgControl pgControl = pgControlFromFile(result->storagePrimary);
@ -864,7 +864,7 @@ backupStart(BackupData *backupData)
else
{
// Check database configuration
checkDbConfig(backupData->version, backupData->pgIdPrimary, backupData->dbPrimary, false);
checkDbConfig(backupData->version, backupData->pgIdxPrimary, backupData->dbPrimary, false);
// Start backup
LOG_INFO_FMT(
@ -897,7 +897,7 @@ backupStart(BackupData *backupData)
dbFree(backupData->dbStandby);
// The standby protocol connection won't be used anymore so free it
protocolRemoteFree(backupData->pgIdStandby);
protocolRemoteFree(backupData->pgIdxStandby);
}
}
}
@ -1588,15 +1588,15 @@ backupProcess(BackupData *backupData, Manifest *manifest, const String *lsnStart
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, backupJobCallback, &jobData);
// First client is always on the primary
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypePg, backupData->pgIdPrimary, 1));
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypePg, backupData->pgIdxPrimary, 1));
// Create the rest of the clients on the primary or standby depending on the value of backup-standby. Note that standby
// backups don't count the primary client in process-max.
unsigned int processMax = cfgOptionUInt(cfgOptProcessMax) + (backupStandby ? 1 : 0);
unsigned int pgId = backupStandby ? backupData->pgIdStandby : backupData->pgIdPrimary;
unsigned int pgIdx = backupStandby ? backupData->pgIdxStandby : backupData->pgIdxPrimary;
for (unsigned int processIdx = 2; processIdx <= processMax; processIdx++)
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypePg, pgId, processIdx));
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypePg, pgIdx, processIdx));
// Maintain a list of files that need to be removed from the manifest when the backup is complete
StringList *fileRemove = strLstNew();
@ -1625,7 +1625,7 @@ backupProcess(BackupData *backupData, Manifest *manifest, const String *lsnStart
manifest,
backupStandby && protocolParallelJobProcessId(job) > 1 ? backupData->hostStandby : backupData->hostPrimary,
storagePathP(
protocolParallelJobProcessId(job) > 1 ? storagePgId(pgId) : backupData->storagePrimary,
protocolParallelJobProcessId(job) > 1 ? storagePgIdx(pgIdx) : backupData->storagePrimary,
manifestPathPg(manifestFileFind(manifest, varStr(protocolParallelJobKey(job)))->name)),
fileRemove, job, sizeTotal, sizeCopied);
}
@ -1997,7 +1997,7 @@ cmdBackup(void)
// The primary protocol connection won't be used anymore so free it. This needs to happen after backupArchiveCheckCopy() so
// the backup lock is held on the remote which allows conditional archiving based on the backup lock. Any further access to
// the primary storage object may result in an error (likely eof).
protocolRemoteFree(backupData->pgIdPrimary);
protocolRemoteFree(backupData->pgIdxPrimary);
// Complete the backup
LOG_INFO_FMT("new backup label = %s", strZ(manifestData(manifest)->backupLabel));

View File

@ -36,7 +36,7 @@ checkManifest(void)
{
result++;
// ??? Placeholder for manifest build
storageListP(storagePgId(pgIdx + 1), varStr(cfgOption(cfgOptPgPath + pgIdx)));
storageListP(storagePgIdx(pgIdx), varStr(cfgOption(cfgOptPgPath + pgIdx)));
}
}
}
@ -70,10 +70,10 @@ checkStandby(const DbGetResult dbGroup, unsigned int pgPathDefinedTotal)
}
// Validate the standby database config
PgControl pgControl = pgControlFromFile(storagePgId(dbGroup.standbyId));
PgControl pgControl = pgControlFromFile(storagePgIdx(dbGroup.standbyIdx));
// Check the user configured path and version against the database
checkDbConfig(pgControl.version, dbGroup.standbyId, dbGroup.standby, true);
checkDbConfig(pgControl.version, dbGroup.standbyIdx, dbGroup.standby, true);
// Get the repo storage in case it is remote and encryption settings need to be pulled down (performed here for testing)
storageRepo();
@ -108,10 +108,10 @@ checkPrimary(const DbGetResult dbGroup)
if (dbGroup.primary != NULL)
{
// Validate the primary database config
PgControl pgControl = pgControlFromFile(storagePgId(dbGroup.primaryId));
PgControl pgControl = pgControlFromFile(storagePgIdx(dbGroup.primaryIdx));
// Check the user configured path and version against the database
checkDbConfig(pgControl.version, dbGroup.primaryId, dbGroup.primary, false);
checkDbConfig(pgControl.version, dbGroup.primaryIdx, dbGroup.primary, false);
// Get the repo storage in case it is remote and encryption settings need to be pulled down (performed here for testing)
storageRepo();

View File

@ -42,23 +42,22 @@ checkArchiveCommand(const String *archiveCommand)
/**********************************************************************************************************************************/
void
checkDbConfig(const unsigned int pgVersion, const unsigned int dbIdx, const Db *dbObject, bool isStandby)
checkDbConfig(const unsigned int pgVersion, const unsigned int pgIdx, const Db *dbObject, bool isStandby)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, pgVersion);
FUNCTION_TEST_PARAM(UINT, dbIdx);
FUNCTION_TEST_PARAM(UINT, pgIdx);
FUNCTION_TEST_PARAM(DB, dbObject);
FUNCTION_TEST_PARAM(BOOL, isStandby);
FUNCTION_TEST_END();
ASSERT(dbIdx > 0);
ASSERT(dbObject != NULL);
MEM_CONTEXT_TEMP_BEGIN()
{
unsigned int dbVersion = dbPgVersion(dbObject);
const String *dbPath = dbPgDataPath(dbObject);
unsigned int pgPath = cfgOptPgPath + (dbIdx - 1);
unsigned int pgPath = cfgOptPgPath + pgIdx;
// 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)
@ -67,7 +66,7 @@ checkDbConfig(const unsigned int pgVersion, const unsigned int dbIdx, const Db *
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.",
strZ(pgVersionToStr(dbVersion)), strZ(dbPath), strZ(pgVersionToStr(pgVersion)), strZ(cfgOptionStr(pgPath)),
strZ(cfgOptionStr(pgPath)), cfgOptionName(pgPath), cfgOptionName(cfgOptPgPort + (dbIdx - 1)));
strZ(cfgOptionStr(pgPath)), cfgOptionName(pgPath), cfgOptionName(cfgOptPgPort + pgIdx));
}
// Check archive configuration if option is valid for the command and set

View File

@ -12,7 +12,7 @@ Check Command Common
Functions
***********************************************************************************************************************************/
// Check the database path and version are configured correctly
void checkDbConfig(const unsigned int pgVersion, const unsigned int dbIdx, const Db *dbObject, bool isStandby);
void checkDbConfig(const unsigned int pgVersion, const unsigned int pgIdx, const Db *dbObject, bool isStandby);
// Validate the archive and backup info files
void checkStanzaInfo(const InfoPgData *archiveInfo, const InfoPgData *backupInfo);

View File

@ -2094,7 +2094,7 @@ cmdRestore(void)
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, restoreJobCallback, &jobData);
for (unsigned int processIdx = 1; processIdx <= cfgOptionUInt(cfgOptProcessMax); processIdx++)
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 1, processIdx));
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 0, processIdx));
// Process jobs
uint64_t sizeRestored = 0;

View File

@ -52,10 +52,10 @@ pgValidate(void)
DbGetResult dbObject = dbGet(false, true, false);
// Get the pgControl information from the pg*-path deemed to be the master
result = pgControlFromFile(storagePgId(dbObject.primaryId));
result = pgControlFromFile(storagePgIdx(dbObject.primaryIdx));
// Check the user configured path and version against the database
checkDbConfig(result.version, dbObject.primaryId, dbObject.primary, false);
checkDbConfig(result.version, dbObject.primaryIdx, dbObject.primary, false);
}
// If the database is not online, assume that pg1 is the master
else

View File

@ -980,7 +980,7 @@ verifyProcess(unsigned int *errorTotal)
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * MSEC_PER_SEC) / 2, verifyJobCallback, &jobData);
for (unsigned int processIdx = 1; processIdx <= cfgOptionUInt(cfgOptProcessMax); processIdx++)
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 1, processIdx));
protocolParallelClientAdd(parallelExec, protocolLocalGet(protocolStorageTypeRepo, 0, processIdx));
// Process jobs
do

View File

@ -12,13 +12,13 @@ Database Helper
/**********************************************************************************************************************************/
static Db *
dbGetId(unsigned int pgId)
dbGetIdx(unsigned int pgIdx)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(UINT, pgId);
FUNCTION_LOG_PARAM(UINT, pgIdx);
FUNCTION_LOG_END();
ASSERT(pgId > 0);
ASSERT(pgIdx < cfgOptionGroupIdxTotal(cfgOptGrpPg));
Db *result = NULL;
@ -26,16 +26,16 @@ dbGetId(unsigned int pgId)
{
const String *applicationName = strNewFmt(PROJECT_NAME " [%s]", cfgCommandName(cfgCommand()));
if (pgIsLocal(pgId))
if (pgIsLocal(pgIdx))
{
result = dbNew(
pgClientNew(
cfgOptionStrNull(cfgOptPgSocketPath + pgId - 1), cfgOptionUInt(cfgOptPgPort + pgId - 1), PG_DB_POSTGRES_STR,
cfgOptionStrNull(cfgOptPgUser + pgId - 1), (TimeMSec)(cfgOptionDbl(cfgOptDbTimeout) * MSEC_PER_SEC)),
cfgOptionStrNull(cfgOptPgSocketPath + pgIdx), cfgOptionUInt(cfgOptPgPort + pgIdx), PG_DB_POSTGRES_STR,
cfgOptionStrNull(cfgOptPgUser + pgIdx), (TimeMSec)(cfgOptionDbl(cfgOptDbTimeout) * MSEC_PER_SEC)),
NULL, applicationName);
}
else
result = dbNew(NULL, protocolRemoteGet(protocolStorageTypePg, pgId), applicationName);
result = dbNew(NULL, protocolRemoteGet(protocolStorageTypePg, pgIdx), applicationName);
dbMove(result, memContextPrior());
}
@ -72,7 +72,7 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
TRY_BEGIN()
{
db = dbGetId(pgIdx + 1);
db = dbGetIdx(pgIdx);
// This needs to be nested because db can be reset to NULL on an error in the outer try but we need the pointer
// to be able to free it.
@ -102,9 +102,9 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
if (standby)
{
// If a standby has not already been found then assign it
if (result.standbyId == 0 && !primaryOnly)
if (result.standby == NULL && !primaryOnly)
{
result.standbyId = pgIdx + 1;
result.standbyIdx = pgIdx;
result.standby = db;
}
// Else close the connection since we don't need it
@ -115,10 +115,10 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
else
{
// Error if more than one primary was found
if (result.primaryId != 0)
if (result.primary != NULL)
THROW(DbConnectError, "more than one primary cluster found");
result.primaryId = pgIdx + 1;
result.primaryIdx = pgIdx;
result.primary = db;
}
}
@ -126,11 +126,11 @@ dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired)
}
// Error if no primary was found
if (result.primaryId == 0 && primaryRequired)
if (result.primary == NULL && primaryRequired)
THROW(DbConnectError, "unable to find primary cluster - cannot proceed");
// Error if no standby was found
if (result.standbyId == 0 && standbyRequired)
if (result.standby == NULL && standbyRequired)
THROW(DbConnectError, "unable to find standby cluster - cannot proceed");
dbMove(result.primary, memContextPrior());

View File

@ -16,10 +16,10 @@ Functions
// Get specified cluster(s)
typedef struct DbGetResult
{
unsigned int primaryId;
Db *primary;
unsigned int standbyId;
Db *standby;
unsigned int primaryIdx; // cfgOptGrpPg index of the primary
Db *primary; // Primary db object (NULL if none requested)
unsigned int standbyIdx; // cfgOptGrpPg index of the standby
Db *standby; // Standby db object (NULL if none requested)
} DbGetResult;
DbGetResult dbGet(bool primaryOnly, bool primaryRequired, bool standbyRequired);

View File

@ -90,15 +90,13 @@ repoIsLocalVerify(void)
/**********************************************************************************************************************************/
bool
pgIsLocal(unsigned int hostId)
pgIsLocal(unsigned int pgIdx)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(UINT, hostId);
FUNCTION_LOG_PARAM(UINT, pgIdx);
FUNCTION_LOG_END();
ASSERT(hostId > 0);
FUNCTION_LOG_RETURN(BOOL, !cfgOptionTest(cfgOptPgHost + hostId - 1));
FUNCTION_LOG_RETURN(BOOL, !cfgOptionTest(cfgOptPgHost + pgIdx));
}
/**********************************************************************************************************************************/
@ -107,7 +105,7 @@ pgIsLocalVerify(void)
{
FUNCTION_TEST_VOID();
if (!pgIsLocal(1))
if (!pgIsLocal(0))
THROW_FMT(HostInvalidError, "%s command must be run on the " PG_NAME " host", cfgCommandName(cfgCommand()));
FUNCTION_TEST_RETURN_VOID();
@ -117,16 +115,14 @@ pgIsLocalVerify(void)
Get the command line required for local protocol execution
***********************************************************************************************************************************/
static StringList *
protocolLocalParam(ProtocolStorageType protocolStorageType, unsigned int hostId, unsigned int protocolId)
protocolLocalParam(ProtocolStorageType protocolStorageType, unsigned int hostIdx, unsigned int processId)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(ENUM, protocolStorageType);
FUNCTION_LOG_PARAM(UINT, hostId);
FUNCTION_LOG_PARAM(UINT, protocolId);
FUNCTION_LOG_PARAM(UINT, hostIdx);
FUNCTION_LOG_PARAM(UINT, processId);
FUNCTION_LOG_END();
ASSERT(hostId > 0);
StringList *result = NULL;
MEM_CONTEXT_TEMP_BEGIN()
@ -135,10 +131,10 @@ protocolLocalParam(ProtocolStorageType protocolStorageType, unsigned int hostId,
KeyValue *optionReplace = kvNew();
// Add the process id -- used when more than one process will be called
kvPut(optionReplace, VARSTR(CFGOPT_PROCESS_STR), VARUINT(protocolId));
kvPut(optionReplace, VARSTR(CFGOPT_PROCESS_STR), VARUINT(processId));
// Add the host id
kvPut(optionReplace, VARSTR(CFGOPT_HOST_ID_STR), VARUINT(hostId));
kvPut(optionReplace, VARSTR(CFGOPT_HOST_ID_STR), VARUINT(hostIdx + 1));
// Add the remote type
kvPut(optionReplace, VARSTR(CFGOPT_REMOTE_TYPE_STR), VARSTR(protocolStorageTypeStr(protocolStorageType)));
@ -163,16 +159,14 @@ protocolLocalParam(ProtocolStorageType protocolStorageType, unsigned int hostId,
/**********************************************************************************************************************************/
ProtocolClient *
protocolLocalGet(ProtocolStorageType protocolStorageType, unsigned int hostId, unsigned int protocolId)
protocolLocalGet(ProtocolStorageType protocolStorageType, unsigned int hostIdx, unsigned int processId)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(ENUM, protocolStorageType);
FUNCTION_LOG_PARAM(UINT, hostId);
FUNCTION_LOG_PARAM(UINT, protocolId);
FUNCTION_LOG_PARAM(UINT, hostIdx);
FUNCTION_LOG_PARAM(UINT, processId);
FUNCTION_LOG_END();
ASSERT(hostId > 0);
protocolHelperInit();
// Allocate the client cache
@ -189,10 +183,10 @@ protocolLocalGet(ProtocolStorageType protocolStorageType, unsigned int hostId, u
MEM_CONTEXT_END();
}
ASSERT(protocolId <= protocolHelper.clientLocalSize);
ASSERT(processId <= protocolHelper.clientLocalSize);
// Create protocol object
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientLocal[protocolId - 1];
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientLocal[processId - 1];
if (protocolHelperClient->client == NULL)
{
@ -200,14 +194,14 @@ protocolLocalGet(ProtocolStorageType protocolStorageType, unsigned int hostId, u
{
// Execute the protocol command
protocolHelperClient->exec = execNew(
cfgExe(), protocolLocalParam(protocolStorageType, hostId, protocolId),
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u process", protocolId),
cfgExe(), protocolLocalParam(protocolStorageType, hostIdx, processId),
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u process", processId),
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
execOpen(protocolHelperClient->exec);
// Create protocol object
protocolHelperClient->client = protocolClientNew(
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u protocol", protocolId),
strNewFmt(PROTOCOL_SERVICE_LOCAL "-%u protocol", processId),
PROTOCOL_SERVICE_LOCAL_STR, execIoRead(protocolHelperClient->exec), execIoWrite(protocolHelperClient->exec));
protocolClientMove(protocolHelperClient->client, execMemContext(protocolHelperClient->exec));
@ -262,18 +256,16 @@ protocolHelperClientFree(ProtocolHelperClient *protocolHelperClient)
/**********************************************************************************************************************************/
void
protocolLocalFree(unsigned int protocolId)
protocolLocalFree(unsigned int processId)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(UINT, protocolId);
FUNCTION_LOG_PARAM(UINT, processId);
FUNCTION_LOG_END();
ASSERT(protocolId > 0);
if (protocolHelper.clientLocal != NULL)
{
ASSERT(protocolId <= protocolHelper.clientLocalSize);
protocolHelperClientFree(&protocolHelper.clientLocal[protocolId - 1]);
ASSERT(processId <= protocolHelper.clientLocalSize);
protocolHelperClientFree(&protocolHelper.clientLocal[processId - 1]);
}
FUNCTION_LOG_RETURN_VOID();
@ -283,11 +275,10 @@ protocolLocalFree(unsigned int protocolId)
Get the command line required for remote protocol execution
***********************************************************************************************************************************/
static StringList *
protocolRemoteParam(ProtocolStorageType protocolStorageType, unsigned int protocolId, unsigned int hostIdx)
protocolRemoteParam(ProtocolStorageType protocolStorageType, unsigned int hostIdx)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(ENUM, protocolStorageType);
FUNCTION_LOG_PARAM(UINT, protocolId);
FUNCTION_LOG_PARAM(UINT, hostIdx);
FUNCTION_LOG_END();
@ -410,9 +401,10 @@ protocolRemoteParam(ProtocolStorageType protocolStorageType, unsigned int protoc
// Don't pass host-id to the remote. The host will always be in index 0.
kvPut(optionReplace, VARSTR(CFGOPT_HOST_ID_STR), NULL);
// Add the process id (or use the current process id if it is valid)
// Add the process id if not set. This means that the remote is being started from the main process and should always get a
// process id of 0.
if (!cfgOptionTest(cfgOptProcess))
kvPut(optionReplace, VARSTR(CFGOPT_PROCESS_STR), VARINT((int)protocolId));
kvPut(optionReplace, VARSTR(CFGOPT_PROCESS_STR), VARINT(0));
// Don't pass log-path or lock-path since these are host specific
kvPut(optionReplace, VARSTR(CFGOPT_LOG_PATH_STR), NULL);
@ -452,15 +444,13 @@ protocolRemoteParam(ProtocolStorageType protocolStorageType, unsigned int protoc
/**********************************************************************************************************************************/
ProtocolClient *
protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostId)
protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostIdx)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(ENUM, protocolStorageType);
FUNCTION_LOG_PARAM(UINT, hostId);
FUNCTION_LOG_PARAM(UINT, hostIdx);
FUNCTION_LOG_END();
ASSERT(hostId > 0);
// Is this a repo remote?
bool isRepo = protocolStorageType == protocolStorageTypeRepo;
@ -488,35 +478,32 @@ protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostId)
// Determine protocol id for the remote. If the process option is set then use that since we want the remote protocol id to
// match the local protocol id. Otherwise set to 0 since the remote is being started from a main process and there should only
// be one remote per host.
unsigned int protocolId = 0;
// Use hostId to determine where to cache to remote
unsigned int protocolIdx = hostId - 1;
unsigned int processId = 0;
if (cfgOptionTest(cfgOptProcess))
protocolId = cfgOptionUInt(cfgOptProcess);
processId = cfgOptionUInt(cfgOptProcess);
CHECK(protocolIdx < protocolHelper.clientRemoteSize);
CHECK(hostIdx < protocolHelper.clientRemoteSize);
// Create protocol object
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientRemote[protocolIdx];
ProtocolHelperClient *protocolHelperClient = &protocolHelper.clientRemote[hostIdx];
if (protocolHelperClient->client == NULL)
{
MEM_CONTEXT_BEGIN(protocolHelper.memContext)
{
unsigned int optHost = isRepo ? cfgOptRepoHost : cfgOptPgHost + hostId - 1;
unsigned int optHost = isRepo ? cfgOptRepoHost : cfgOptPgHost + hostIdx;
// Execute the protocol command
protocolHelperClient->exec = execNew(
cfgOptionStr(cfgOptCmdSsh), protocolRemoteParam(protocolStorageType, protocolId, hostId - 1),
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u process on '%s'", protocolId, strZ(cfgOptionStr(optHost))),
cfgOptionStr(cfgOptCmdSsh), protocolRemoteParam(protocolStorageType, hostIdx),
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u process on '%s'", processId, strZ(cfgOptionStr(optHost))),
(TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
execOpen(protocolHelperClient->exec);
// Create protocol object
protocolHelperClient->client = protocolClientNew(
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u protocol on '%s'", protocolId, strZ(cfgOptionStr(optHost))),
strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u protocol on '%s'", processId, strZ(cfgOptionStr(optHost))),
PROTOCOL_SERVICE_REMOTE_STR, execIoRead(protocolHelperClient->exec), execIoWrite(protocolHelperClient->exec));
// Get cipher options from the remote if none are locally configured
@ -546,16 +533,14 @@ protocolRemoteGet(ProtocolStorageType protocolStorageType, unsigned int hostId)
/**********************************************************************************************************************************/
void
protocolRemoteFree(unsigned int hostId)
protocolRemoteFree(unsigned int hostIdx)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(UINT, hostId);
FUNCTION_LOG_PARAM(UINT, hostIdx);
FUNCTION_LOG_END();
ASSERT(hostId > 0);
if (protocolHelper.clientRemote != NULL)
protocolHelperClientFree(&protocolHelper.clientRemote[hostId - 1]);
protocolHelperClientFree(&protocolHelper.clientRemote[hostIdx]);
FUNCTION_LOG_RETURN_VOID();
}
@ -627,7 +612,7 @@ protocolFree(void)
{
// Free remotes
for (unsigned int clientIdx = 0; clientIdx < protocolHelper.clientRemoteSize; clientIdx++)
protocolRemoteFree(clientIdx + 1);
protocolRemoteFree(clientIdx);
// Free locals
for (unsigned int clientIdx = 1; clientIdx <= protocolHelper.clientLocalSize; clientIdx++)

View File

@ -48,7 +48,7 @@ void protocolRemoteFree(unsigned int hostId);
Getters/Setters
***********************************************************************************************************************************/
// Is pg local?
bool pgIsLocal(unsigned int hostId);
bool pgIsLocal(unsigned int pgIdx);
// Error if PostgreSQL is not local, i.e. pg-host is set
void pgIsLocalVerify(void);

View File

@ -164,26 +164,26 @@ storageLocalWrite(void)
Get pg storage for the specified host id
***********************************************************************************************************************************/
static Storage *
storagePgGet(unsigned int hostId, bool write)
storagePgGet(unsigned int pgIdx, bool write)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, hostId);
FUNCTION_TEST_PARAM(UINT, pgIdx);
FUNCTION_TEST_PARAM(BOOL, write);
FUNCTION_TEST_END();
Storage *result = NULL;
// Use remote storage
if (!pgIsLocal(hostId))
if (!pgIsLocal(pgIdx))
{
result = storageRemoteNew(
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, NULL,
protocolRemoteGet(protocolStorageTypePg, hostId), cfgOptionUInt(cfgOptCompressLevelNetwork));
protocolRemoteGet(protocolStorageTypePg, pgIdx), cfgOptionUInt(cfgOptCompressLevelNetwork));
}
// Use Posix storage
else
{
result = storagePosixNewP(cfgOptionStr(cfgOptPgPath + hostId - 1), .write = write);
result = storagePosixNewP(cfgOptionStr(cfgOptPgPath + pgIdx), .write = write);
}
FUNCTION_TEST_RETURN(result);
@ -191,13 +191,13 @@ storagePgGet(unsigned int hostId, bool write)
/**********************************************************************************************************************************/
const Storage *
storagePgId(unsigned int hostId)
storagePgIdx(unsigned int pgIdx)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, hostId);
FUNCTION_TEST_PARAM(UINT, pgIdx);
FUNCTION_TEST_END();
if (storageHelper.storagePg == NULL || storageHelper.storagePg[hostId - 1] == NULL)
if (storageHelper.storagePg == NULL || storageHelper.storagePg[pgIdx] == NULL)
{
storageHelperInit();
@ -206,33 +206,33 @@ storagePgId(unsigned int hostId)
if (storageHelper.storagePg == NULL)
storageHelper.storagePg = memNewPtrArray(cfgDefOptionIndexTotal(cfgDefOptPgPath));
storageHelper.storagePg[hostId - 1] = storagePgGet(hostId, false);
storageHelper.storagePg[pgIdx] = storagePgGet(pgIdx, false);
}
MEM_CONTEXT_END();
}
FUNCTION_TEST_RETURN(storageHelper.storagePg[hostId - 1]);
FUNCTION_TEST_RETURN(storageHelper.storagePg[pgIdx]);
}
const Storage *
storagePg(void)
{
FUNCTION_TEST_VOID();
FUNCTION_TEST_RETURN(storagePgId(cfgOptionTest(cfgOptHostId) ? cfgOptionUInt(cfgOptHostId) : 1));
FUNCTION_TEST_RETURN(storagePgIdx(cfgOptionTest(cfgOptHostId) ? cfgOptionUInt(cfgOptHostId) - 1 : 0));
}
const Storage *
storagePgIdWrite(unsigned int hostId)
storagePgIdxWrite(unsigned int pgIdx)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(UINT, hostId);
FUNCTION_TEST_PARAM(UINT, pgIdx);
FUNCTION_TEST_END();
// Writes not allowed in dry-run mode
if (!storageHelper.dryRunInit || storageHelper.dryRun)
THROW(AssertError, WRITABLE_WHILE_DRYRUN);
if (storageHelper.storagePgWrite == NULL || storageHelper.storagePgWrite[hostId - 1] == NULL)
if (storageHelper.storagePgWrite == NULL || storageHelper.storagePgWrite[pgIdx] == NULL)
{
storageHelperInit();
@ -241,19 +241,19 @@ storagePgIdWrite(unsigned int hostId)
if (storageHelper.storagePgWrite == NULL)
storageHelper.storagePgWrite = memNewPtrArray(cfgDefOptionIndexTotal(cfgDefOptPgPath));
storageHelper.storagePgWrite[hostId - 1] = storagePgGet(hostId, true);
storageHelper.storagePgWrite[pgIdx] = storagePgGet(pgIdx, true);
}
MEM_CONTEXT_END();
}
FUNCTION_TEST_RETURN(storageHelper.storagePgWrite[hostId - 1]);
FUNCTION_TEST_RETURN(storageHelper.storagePgWrite[pgIdx]);
}
const Storage *
storagePgWrite(void)
{
FUNCTION_TEST_VOID();
FUNCTION_TEST_RETURN(storagePgIdWrite(cfgOptionTest(cfgOptHostId) ? cfgOptionUInt(cfgOptHostId) : 1));
FUNCTION_TEST_RETURN(storagePgIdxWrite(cfgOptionTest(cfgOptHostId) ? cfgOptionUInt(cfgOptHostId) - 1 : 0));
}
/***********************************************************************************************************************************
@ -349,7 +349,7 @@ storageRepoGet(const String *type, bool write)
{
result = storageRemoteNew(
STORAGE_MODE_FILE_DEFAULT, STORAGE_MODE_PATH_DEFAULT, write, storageRepoPathExpression,
protocolRemoteGet(protocolStorageTypeRepo, 1), cfgOptionUInt(cfgOptCompressLevelNetwork));
protocolRemoteGet(protocolStorageTypeRepo, 0), cfgOptionUInt(cfgOptCompressLevelNetwork));
}
// Use Azure storage
else if (strEqZ(type, STORAGE_AZURE_TYPE))

View File

@ -37,11 +37,11 @@ void storageHelperDryRunInit(bool dryRun);
const Storage *storageLocal(void);
const Storage *storageLocalWrite(void);
// PostgreSQL storage by Id
const Storage *storagePgId(unsigned int hostId);
const Storage *storagePgIdWrite(unsigned int hostId);
// PostgreSQL storage by cfgOptGrpPg index
const Storage *storagePgIdx(unsigned int pgIdx);
const Storage *storagePgIdxWrite(unsigned int pgIdx);
// PostgreSQL storage for the host-id or the default of 1
// PostgreSQL storage default (calculated from host-id, when set, or the first cfgOptGrpPg index)
const Storage *storagePg(void);
const Storage *storagePgWrite(void);

View File

@ -2107,28 +2107,28 @@ testRun(void)
// Create file to copy from the standby. This file will be zero-length on the primary and non-zero-length on the standby
// but no bytes will be copied.
storagePutP(storageNewWriteP(storagePgIdWrite(1), STRDEF(PG_PATH_BASE "/1/1"), .timeModified = backupTimeStart), NULL);
storagePutP(storageNewWriteP(storagePgIdWrite(2), STRDEF(PG_PATH_BASE "/1/1")), BUFSTRDEF("1234"));
storagePutP(storageNewWriteP(storagePgIdxWrite(0), STRDEF(PG_PATH_BASE "/1/1"), .timeModified = backupTimeStart), NULL);
storagePutP(storageNewWriteP(storagePgIdxWrite(1), STRDEF(PG_PATH_BASE "/1/1")), BUFSTRDEF("1234"));
// Create file to copy from the standby. This file will be smaller on the primary than the standby and have no common
// data in the bytes that exist on primary and standby. If the file is copied from the primary instead of the standby
// the checksum will change but not the size.
storagePutP(
storageNewWriteP(storagePgIdWrite(1), STRDEF(PG_PATH_BASE "/1/2"), .timeModified = backupTimeStart),
storageNewWriteP(storagePgIdxWrite(0), STRDEF(PG_PATH_BASE "/1/2"), .timeModified = backupTimeStart),
BUFSTRDEF("DA"));
storagePutP(storageNewWriteP(storagePgIdWrite(2), STRDEF(PG_PATH_BASE "/1/2")), BUFSTRDEF("5678"));
storagePutP(storageNewWriteP(storagePgIdxWrite(1), STRDEF(PG_PATH_BASE "/1/2")), BUFSTRDEF("5678"));
// Create file to copy from the standby. This file will be larger on the primary than the standby and have no common
// data in the bytes that exist on primary and standby. If the file is copied from the primary instead of the standby
// the checksum and size will change.
storagePutP(
storageNewWriteP(storagePgIdWrite(1), STRDEF(PG_PATH_BASE "/1/3"), .timeModified = backupTimeStart),
storageNewWriteP(storagePgIdxWrite(0), STRDEF(PG_PATH_BASE "/1/3"), .timeModified = backupTimeStart),
BUFSTRDEF("TEST"));
storagePutP(storageNewWriteP(storagePgIdWrite(2), STRDEF(PG_PATH_BASE "/1/3")), BUFSTRDEF("ABC"));
storagePutP(storageNewWriteP(storagePgIdxWrite(1), STRDEF(PG_PATH_BASE "/1/3")), BUFSTRDEF("ABC"));
// Create a file on the primary that does not exist on the standby to test that the file is removed from the manifest
storagePutP(
storageNewWriteP(storagePgIdWrite(1), STRDEF(PG_PATH_BASE "/1/0"), .timeModified = backupTimeStart),
storageNewWriteP(storagePgIdxWrite(0), STRDEF(PG_PATH_BASE "/1/0"), .timeModified = backupTimeStart),
BUFSTRDEF("DATA"));
// Set log level to warn because the following test uses multiple processes so the log order will not be deterministic
@ -2200,7 +2200,7 @@ testRun(void)
"compare file list");
// Remove test files
storagePathRemoveP(storagePgIdWrite(2), NULL, .recurse = true);
storagePathRemoveP(storagePgIdxWrite(1), NULL, .recurse = true);
storagePathRemoveP(storagePgWrite(), STRDEF("base/1"), .recurse = true);
}

View File

@ -371,12 +371,12 @@ testRun(void)
TEST_ASSIGN(db, dbGet(false, false, false), "get primary and standby");
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryId, db.primary, false), "valid db config");
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config");
// Version mismatch
// -------------------------------------------------------------------------------------------------------------------------
TEST_ERROR_FMT(
checkDbConfig(PG_VERSION_94, db.primaryId, db.primary, false), DbMismatchError,
checkDbConfig(PG_VERSION_94, db.primaryIdx, db.primary, false), 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.",
@ -385,7 +385,7 @@ testRun(void)
// Path mismatch
// -------------------------------------------------------------------------------------------------------------------------
TEST_ERROR_FMT(
checkDbConfig(PG_VERSION_92, db.standbyId, db.standby, true), DbMismatchError,
checkDbConfig(PG_VERSION_92, db.standbyIdx, db.standby, true), 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 pg8-path and pg8-port settings likely reference different clusters.",
@ -397,7 +397,7 @@ testRun(void)
strLstAddZ(argList, "--no-archive-check");
harnessCfgLoad(cfgCmdCheck, argList);
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryId, db.primary, false), "valid db config --no-archive-check");
TEST_RESULT_VOID(checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config --no-archive-check");
// archive-check not valid for command
// -------------------------------------------------------------------------------------------------------------------------
@ -410,7 +410,7 @@ testRun(void)
harnessCfgLoad(cfgCmdStanzaCreate, argList);
TEST_RESULT_VOID(
checkDbConfig(PG_VERSION_92, db.primaryId, db.primary, false), "valid db config, archive-check not valid for command");
checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), "valid db config, archive-check not valid for command");
TEST_RESULT_VOID(dbFree(db.primary), "free primary");
TEST_RESULT_VOID(dbFree(db.standby), "free standby");
@ -432,7 +432,7 @@ testRun(void)
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
TEST_ERROR_FMT(
checkDbConfig(PG_VERSION_92, db.primaryId, db.primary, false), FeatureNotSupportedError,
checkDbConfig(PG_VERSION_92, db.primaryIdx, db.primary, false), FeatureNotSupportedError,
"archive_mode=always not supported");
TEST_RESULT_VOID(dbFree(db.primary), "free primary");

View File

@ -213,7 +213,7 @@ testRun(void)
HRNPQ_MACRO_DONE()
});
DbGetResult db = {.primaryId = 0};
DbGetResult db = {0};
TEST_ASSIGN(db, dbGet(true, true, false), "get primary");
TEST_RESULT_STR_Z(dbBackupStart(db.primary, false, false).lsn, "1/1", "start backup");
@ -558,9 +558,9 @@ testRun(void)
TEST_ASSIGN(result, dbGet(true, true, false), "get primary only");
TEST_RESULT_INT(result.primaryId, 1, " check primary id");
TEST_RESULT_INT(result.primaryIdx, 0, " check primary id");
TEST_RESULT_BOOL(result.primary != NULL, true, " check primary");
TEST_RESULT_INT(result.standbyId, 0, " check standby id");
TEST_RESULT_INT(result.standbyIdx, 0, " check standby id");
TEST_RESULT_BOOL(result.standby == NULL, true, " check standby");
TEST_RESULT_INT(dbPgVersion(result.primary), PG_VERSION_84, " version set");
TEST_RESULT_STR_Z(dbPgDataPath(result.primary), "/pgdata", " path set");
@ -620,9 +620,9 @@ testRun(void)
TEST_ASSIGN(result, dbGet(false, false, false), "get standbys");
TEST_RESULT_INT(result.primaryId, 0, " check primary id");
TEST_RESULT_INT(result.primaryIdx, 0, " check primary id");
TEST_RESULT_BOOL(result.primary == NULL, true, " check primary");
TEST_RESULT_INT(result.standbyId, 1, " check standby id");
TEST_RESULT_INT(result.standbyIdx, 0, " check standby id");
TEST_RESULT_BOOL(result.standby != NULL, true, " check standby");
TEST_RESULT_VOID(dbFree(result.standby), "free standby");
@ -671,12 +671,12 @@ testRun(void)
"P00 WARN: unable to check pg-5: [DbConnectError] raised from remote-0 protocol on 'localhost':"
" unable to connect to 'dbname='postgres' port=5432': could not connect to server: [NO SUCH FILE OR DIRECTORY]");
TEST_RESULT_INT(result.primaryId, 8, " check primary id");
TEST_RESULT_INT(result.primaryIdx, 7, " check primary id");
TEST_RESULT_BOOL(result.primary != NULL, true, " check primary");
TEST_RESULT_STR_Z(dbArchiveMode(result.primary), "on", " dbArchiveMode");
TEST_RESULT_STR_Z(dbArchiveCommand(result.primary), PROJECT_BIN, " dbArchiveCommand");
TEST_RESULT_STR_Z(dbWalSwitch(result.primary), "000000010000000200000003", " wal switch");
TEST_RESULT_INT(result.standbyId, 1, " check standby id");
TEST_RESULT_INT(result.standbyIdx, 0, " check standby id");
TEST_RESULT_BOOL(result.standby != NULL, true, " check standby");
TEST_RESULT_VOID(dbFree(result.primary), "free primary");

View File

@ -159,7 +159,7 @@ testRun(void)
strLstAddZ(argList, "backup");
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_BOOL(pgIsLocal(1), true, "pg is local");
TEST_RESULT_BOOL(pgIsLocal(0), true, "pg is local");
TEST_RESULT_VOID(pgIsLocalVerify(), "verify pg is local");
// -------------------------------------------------------------------------------------------------------------------------
@ -173,7 +173,7 @@ testRun(void)
strLstAddZ(argList, "restore");
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_BOOL(pgIsLocal(1), false, "pg is remote");
TEST_RESULT_BOOL(pgIsLocal(0), false, "pg1 is remote");
TEST_ERROR_FMT(pgIsLocalVerify(), HostInvalidError, "restore command must be run on the PostgreSQL host");
// -------------------------------------------------------------------------------------------------------------------------
@ -192,7 +192,7 @@ testRun(void)
strLstAddZ(argList, CFGCMD_BACKUP ":" CONFIG_COMMAND_ROLE_LOCAL);
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_BOOL(pgIsLocal(7), false, "pg is remote");
TEST_RESULT_BOOL(pgIsLocal(6), false, "pg7 is remote");
}
// *****************************************************************************************************************************
@ -227,7 +227,7 @@ testRun(void)
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_STR_Z(
strLstJoin(protocolLocalParam(protocolStorageTypeRepo, 1, 0), "|"),
strLstJoin(protocolLocalParam(protocolStorageTypeRepo, 0, 0), "|"),
"--host-id=1|--log-level-console=off|--log-level-file=off|--log-level-stderr=error|--pg1-path=/path/to/pg|--process=0"
"|--remote-type=repo|--stanza=test1|archive-get:local",
"local repo protocol params");
@ -243,8 +243,8 @@ testRun(void)
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_STR_Z(
strLstJoin(protocolLocalParam(protocolStorageTypePg, 2, 1), "|"),
"--host-id=2|--log-level-console=off|--log-level-file=info|--log-level-stderr=error|--log-subprocess|--pg1-path=/pg"
strLstJoin(protocolLocalParam(protocolStorageTypePg, 0, 1), "|"),
"--host-id=1|--log-level-console=off|--log-level-file=info|--log-level-stderr=error|--log-subprocess|--pg1-path=/pg"
"|--process=1|--remote-type=pg|--repo1-retention-full=1|--stanza=test1|backup:local",
"local pg protocol params");
}
@ -268,7 +268,7 @@ testRun(void)
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_STR_Z(
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0, 0), "|"),
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0), "|"),
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|repo-host-user@repo-host"
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-path=/path/to/pg"
" --process=0 --remote-type=repo --repo1-local --stanza=test1 archive-get:remote",
@ -291,11 +291,11 @@ testRun(void)
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_STR_Z(
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 1, 0), "|"),
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0), "|"),
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|-p|444|repo-host-user@repo-host"
"|pgbackrest --config=/path/pgbackrest.conf --config-include-path=/path/include --config-path=/path/config"
" --log-level-console=off --log-level-file=info --log-level-stderr=error --log-subprocess --pg1-path=/unused"
" --process=1 --remote-type=repo --repo1-local --stanza=test1 check:remote",
" --process=0 --remote-type=repo --repo1-local --stanza=test1 check:remote",
"remote protocol params with replacements");
// -------------------------------------------------------------------------------------------------------------------------
@ -311,7 +311,7 @@ testRun(void)
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_STR_Z(
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 66, 0), "|"),
strLstJoin(protocolRemoteParam(protocolStorageTypeRepo, 0), "|"),
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|pgbackrest@repo-host"
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-path=/path/to/pg"
" --process=3 --remote-type=repo --repo1-local --stanza=test1 archive-get:remote",
@ -328,10 +328,10 @@ testRun(void)
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_STR_Z(
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 0), "|"),
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 0), "|"),
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|postgres@pg1-host"
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-local"
" --pg1-path=/path/to/1 --process=1 --remote-type=pg --stanza=test1 backup:remote",
" --pg1-path=/path/to/1 --process=0 --remote-type=pg --stanza=test1 backup:remote",
"remote protocol params for db backup");
// -------------------------------------------------------------------------------------------------------------------------
@ -351,7 +351,7 @@ testRun(void)
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_STR_Z(
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 1), "|"),
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1), "|"),
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|postgres@pg2-host"
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-local"
" --pg1-path=/path/to/2 --process=4 --remote-type=pg --stanza=test1 backup:remote",
@ -374,7 +374,7 @@ testRun(void)
harnessCfgLoadRaw(strLstSize(argList), strLstPtr(argList));
TEST_RESULT_STR_Z(
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 1, 2), "|"),
strLstJoin(protocolRemoteParam(protocolStorageTypePg, 2), "|"),
"-o|LogLevel=error|-o|Compression=no|-o|PasswordAuthentication=no|postgres@pg3-host"
"|pgbackrest --log-level-console=off --log-level-file=off --log-level-stderr=error --pg1-local"
" --pg1-path=/path/to/3 --pg1-port=3333 --pg1-socket-path=/socket3 --process=4 --remote-type=pg --stanza=test1"
@ -953,8 +953,8 @@ testRun(void)
TEST_RESULT_VOID(protocolFree(), "free protocol objects before anything has been created");
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 1), "get remote protocol");
TEST_RESULT_PTR(protocolRemoteGet(protocolStorageTypeRepo, 1), client, "get remote cached protocol");
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 0), "get remote protocol");
TEST_RESULT_PTR(protocolRemoteGet(protocolStorageTypeRepo, 0), client, "get remote cached protocol");
TEST_RESULT_PTR(protocolHelper.clientRemote[0].client, client, "check position in cache");
TEST_RESULT_VOID(protocolKeepAlive(), "keep alive");
TEST_RESULT_VOID(protocolFree(), "free remote protocol objects");
@ -983,7 +983,7 @@ testRun(void)
harnessCfgLoadRole(cfgCmdArchiveGet, cfgCmdRoleLocal, argList);
TEST_RESULT_STR_Z(cfgOptionStr(cfgOptRepoCipherPass), "acbd", "check cipher pass before");
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 1), "get remote protocol");
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 0), "get remote protocol");
TEST_RESULT_PTR(protocolHelper.clientRemote[0].client, client, "check position in cache");
TEST_RESULT_STR_Z(cfgOptionStr(cfgOptRepoCipherPass), "acbd", "check cipher pass after");
@ -1008,7 +1008,7 @@ testRun(void)
harnessCfgLoad(cfgCmdInfo, argList);
TEST_RESULT_PTR(cfgOptionStrNull(cfgOptRepoCipherPass), NULL, "check cipher pass before");
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 1), "get remote protocol");
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypeRepo, 0), "get remote protocol");
TEST_RESULT_STR_Z(cfgOptionStr(cfgOptRepoCipherPass), "dcba", "check cipher pass after");
TEST_RESULT_VOID(protocolFree(), "free remote protocol objects");
@ -1024,7 +1024,9 @@ testRun(void)
strLstAdd(argList, strNewFmt("--pg1-path=%s", testPath()));
harnessCfgLoad(cfgCmdBackup, argList);
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypePg, 1), "get remote protocol");
TEST_ASSIGN(client, protocolRemoteGet(protocolStorageTypePg, 0), "get remote protocol");
TEST_RESULT_VOID(protocolFree(), "free local and remote protocol objects");
// Start local protocol
// -------------------------------------------------------------------------------------------------------------------------
@ -1035,8 +1037,8 @@ testRun(void)
strLstAddZ(argList, "--process-max=2");
harnessCfgLoad(cfgCmdArchiveGet, argList);
TEST_ASSIGN(client, protocolLocalGet(protocolStorageTypeRepo, 1, 1), "get local protocol");
TEST_RESULT_PTR(protocolLocalGet(protocolStorageTypeRepo, 1, 1), client, "get local cached protocol");
TEST_ASSIGN(client, protocolLocalGet(protocolStorageTypeRepo, 0, 1), "get local protocol");
TEST_RESULT_PTR(protocolLocalGet(protocolStorageTypeRepo, 0, 1), client, "get local cached protocol");
TEST_RESULT_PTR(protocolHelper.clientLocal[0].client, client, "check location in cache");
TEST_RESULT_VOID(protocolFree(), "free local and remote protocol objects");

View File

@ -68,7 +68,7 @@ testRun(void)
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("writable storage fails when dry-run is not initialized");
TEST_ERROR(storagePgIdWrite(1), AssertError, WRITABLE_WHILE_DRYRUN);
TEST_ERROR(storagePgIdxWrite(0), AssertError, WRITABLE_WHILE_DRYRUN);
TEST_ERROR(storageRepoWrite(), AssertError, WRITABLE_WHILE_DRYRUN);
TEST_ERROR(storageSpoolWrite(), AssertError, WRITABLE_WHILE_DRYRUN);
@ -77,7 +77,7 @@ testRun(void)
storageHelperDryRunInit(true);
TEST_ERROR(storagePgIdWrite(1), AssertError, WRITABLE_WHILE_DRYRUN);
TEST_ERROR(storagePgIdxWrite(0), AssertError, WRITABLE_WHILE_DRYRUN);
TEST_ERROR(storageRepoWrite(), AssertError, WRITABLE_WHILE_DRYRUN);
TEST_ERROR(storageSpoolWrite(), AssertError, WRITABLE_WHILE_DRYRUN);
}
@ -1282,24 +1282,17 @@ testRun(void)
TEST_RESULT_STR(storage->path, strNewFmt("%s/db", testPath()), "check pg storage path");
TEST_RESULT_BOOL(storage->write, false, "check pg storage write");
TEST_RESULT_STR(storagePgId(2)->path, strNewFmt("%s/db2", testPath()), "check pg 2 storage path");
TEST_RESULT_STR(storagePgIdx(1)->path, strNewFmt("%s/db2", testPath()), "check pg 2 storage path");
TEST_RESULT_PTR(storageHelper.storagePgWrite, NULL, "pg write storage not cached");
TEST_ASSIGN(storage, storagePgWrite(), "new pg write storage");
TEST_RESULT_PTR(storageHelper.storagePgWrite[0], storage, "pg write storage cached");
TEST_RESULT_PTR(storagePgWrite(), storage, "get cached pg write storage");
TEST_RESULT_STR(storagePgIdWrite(2)->path, strNewFmt("%s/db2", testPath()), "check pg 2 write storage path");
TEST_RESULT_STR(storagePgIdxWrite(1)->path, strNewFmt("%s/db2", testPath()), "check pg 2 write storage path");
TEST_RESULT_STR(storage->path, strNewFmt("%s/db", testPath()), "check pg write storage path");
TEST_RESULT_BOOL(storage->write, true, "check pg write storage write");
// Pg storage from another host id
// -------------------------------------------------------------------------------------------------------------------------
cfgOptionSet(cfgOptHostId, cfgSourceParam, VARUINT64(2));
cfgOptionValidSet(cfgOptHostId, true);
TEST_RESULT_STR(storagePg()->path, strNewFmt("%s/db2", testPath()), "check pg-2 storage path");
// Change the stanza to NULL, stanzaInit flag to false and make sure helper fails because stanza is required
// -------------------------------------------------------------------------------------------------------------------------
storageHelper.storageSpool = NULL;