1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-12 10:04:14 +02:00

Improve stop command to honor stanza option.

Improve the stop command, when force and stanza options are specified, to terminate only processes holding lock files for the given stanza. Prior to these changes, termination of all processes holding lock files regardless of stanza occurred.
This commit is contained in:
Reid Thompson 2022-03-08 13:18:23 -05:00 committed by GitHub
parent 514137040e
commit f7ab002aa7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 99 additions and 15 deletions

View File

@ -27,6 +27,19 @@
<p>Increase precision of percent complete logging for <cmd>backup</cmd> and <cmd>restore</cmd>.</p>
</release-item>
<release-item>
<github-issue id="1608"/>
<github-pull-request id="1676"/>
<release-item-contributor-list>
<release-item-ideator id="ragaoua"/>
<release-item-contributor id="reid.thompson"/>
<release-item-reviewer id="david.steele"/>
</release-item-contributor-list>
<p>Improve <cmd>stop</cmd> command to honor <br-option>stanza</br-option> option.</p>
</release-item>
</release-improvement-list>
<release-development-list>
@ -11411,6 +11424,11 @@
<contributor-id type="github">rachid-casa</contributor-id>
</contributor>
<contributor id="ragaoua">
<contributor-name-display>ragaoua</contributor-name-display>
<contributor-id type="github">ragaoua</contributor-id>
</contributor>
<contributor id="rakshitha.br">
<contributor-name-display>Rakshitha-BR</contributor-name-display>
<contributor-id type="github">Rakshitha-BR</contributor-id>

View File

@ -59,11 +59,19 @@ cmdStop(void)
// Find each lock file and send term signals to the processes
for (unsigned int lockPathFileIdx = 0; lockPathFileIdx < strLstSize(lockPathFileList); lockPathFileIdx++)
{
String *lockFile = strNewFmt("%s/%s", strZ(lockPath), strZ(strLstGet(lockPathFileList, lockPathFileIdx)));
const String *lockFile = strLstGet(lockPathFileList, lockPathFileIdx);
// Skip any file that is not a lock file
if (!strEndsWithZ(lockFile, LOCK_FILE_EXT))
// Skip any file that is not a lock file. Skip lock files for other stanzas if a stanza is provided.
if (!strEndsWithZ(lockFile, LOCK_FILE_EXT) ||
(cfgOptionTest(cfgOptStanza) &&
!strEq(lockFile, lockFileName(cfgOptionStr(cfgOptStanza), lockTypeArchive)) &&
!strEq(lockFile, lockFileName(cfgOptionStr(cfgOptStanza), lockTypeBackup))))
{
continue;
}
// Add path to the lock file
lockFile = strNewFmt("%s/%s", strZ(lockPath), strZ(lockFile));
// If we cannot open the lock file for any reason then warn and continue to next file
if ((fd = open(strZ(lockFile), O_RDONLY, 0)) == -1)

View File

@ -58,6 +58,18 @@ static struct LockLocal
.held = lockTypeNone,
};
/**********************************************************************************************************************************/
String *
lockFileName(const String *const stanza, const LockType lockType)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STRING, stanza);
FUNCTION_TEST_PARAM(ENUM, lockType);
FUNCTION_TEST_END();
FUNCTION_TEST_RETURN(strNewFmt("%s-%s" LOCK_FILE_EXT, strZ(stanza), lockTypeName[lockType]));
}
/***********************************************************************************************************************************
Read contents of lock file
@ -285,7 +297,7 @@ lockAcquire(
{
MEM_CONTEXT_BEGIN(lockLocal.memContext)
{
lockLocal.file[lockIdx].name = strNewFmt("%s/%s-%s" LOCK_FILE_EXT, strZ(lockPath), strZ(stanza), lockTypeName[lockIdx]);
lockLocal.file[lockIdx].name = strNewFmt("%s/%s", strZ(lockPath), strZ(lockFileName(stanza, lockIdx)));
}
MEM_CONTEXT_END();

View File

@ -42,4 +42,7 @@ bool lockAcquire(
// Release a lock
bool lockRelease(bool failOnNoLock);
// Build lock file name
String *lockFileName(const String *stanza, LockType lockType);
#endif

View File

@ -687,7 +687,7 @@ unit:
test:
# ----------------------------------------------------------------------------------------------------------------------------
- name: control
total: 3
total: 4
coverage:
- command/control/common

View File

@ -139,16 +139,17 @@ testRun(void)
TEST_TITLE("unable to open lock file");
HRN_STORAGE_PUT_EMPTY(
hrnStorage, "lock/bad" LOCK_FILE_EXT, .modeFile = 0222, .comment = "create a lock file that cannot be opened");
hrnStorage, "lock/db-archive" LOCK_FILE_EXT, .modeFile = 0222,
.comment = "create a lock file that cannot be opened");
TEST_RESULT_VOID(cmdStop(), "stanza, create stop file but unable to open lock file");
TEST_STORAGE_EXISTS(hrnStorage, "lock/db" STOP_FILE_EXT, .comment = "stanza stop file created");
TEST_RESULT_LOG("P00 WARN: unable to open lock file " HRN_PATH "/lock/bad" LOCK_FILE_EXT);
TEST_RESULT_LOG("P00 WARN: unable to open lock file " HRN_PATH "/lock/db-archive" LOCK_FILE_EXT);
HRN_STORAGE_PATH_REMOVE(hrnStorage, "lock", .recurse = true, .errorOnMissing = true, .comment = "remove the lock path");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("lock file removal");
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/empty" LOCK_FILE_EXT, .comment = "create empty lock file");
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, .comment = "create empty lock file");
TEST_RESULT_VOID(cmdStop(), "stanza, create stop file, force - empty lock file");
TEST_STORAGE_LIST(
hrnStorage, "lock", "db" STOP_FILE_EXT "\n",
@ -158,13 +159,13 @@ testRun(void)
TEST_TITLE("empty lock file with another process lock, processId == NULL");
HRN_STORAGE_REMOVE(hrnStorage, "lock/db" STOP_FILE_EXT, .errorOnMissing = true, .comment = "remove stanza stop file");
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/empty" LOCK_FILE_EXT, .comment = "create empty lock file");
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, .comment = "create empty lock file");
HRN_FORK_BEGIN()
{
HRN_FORK_CHILD_BEGIN()
{
int lockFd = open(HRN_PATH "/lock/empty" LOCK_FILE_EXT, O_RDONLY, 0);
int lockFd = open(HRN_PATH "/lock/db-backup" LOCK_FILE_EXT, O_RDONLY, 0);
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the empty file");
@ -200,13 +201,13 @@ testRun(void)
TEST_TITLE("not empty lock file with another process lock, processId size trimmed to 0");
HRN_STORAGE_REMOVE(hrnStorage, "lock/db" STOP_FILE_EXT, .errorOnMissing = true, .comment = "remove stanza stop file");
HRN_STORAGE_PUT_Z(hrnStorage, "lock/empty" LOCK_FILE_EXT, " ", .comment = "create non-empty lock file");
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, " ", .comment = "create non-empty lock file");
HRN_FORK_BEGIN()
{
HRN_FORK_CHILD_BEGIN()
{
int lockFd = open(HRN_PATH "/lock/empty" LOCK_FILE_EXT, O_RDONLY, 0);
int lockFd = open(HRN_PATH "/lock/db-backup" LOCK_FILE_EXT, O_RDONLY, 0);
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the non-empty file");
@ -276,13 +277,13 @@ testRun(void)
TEST_TITLE("lock file with another process lock, processId is invalid");
HRN_STORAGE_REMOVE(hrnStorage, "lock/db" STOP_FILE_EXT, .errorOnMissing = true, .comment = "remove stanza stop file");
HRN_STORAGE_PUT_Z(hrnStorage, "lock/badpid" LOCK_FILE_EXT, "-32768", .comment = "create lock file with invalid PID");
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, "-32768", .comment = "create lock file with invalid PID");
HRN_FORK_BEGIN()
{
HRN_FORK_CHILD_BEGIN()
{
int lockFd = open(HRN_PATH "/lock/badpid" LOCK_FILE_EXT, O_RDONLY, 0);
int lockFd = open(HRN_PATH "/lock/db-backup" LOCK_FILE_EXT, O_RDONLY, 0);
TEST_RESULT_BOOL(lockFd != -1, true, "file descriptor acquired");
TEST_RESULT_INT(flock(lockFd, LOCK_EX | LOCK_NB), 0, "lock the badpid file");
@ -293,7 +294,7 @@ testRun(void)
HRN_FORK_CHILD_NOTIFY_GET();
// Remove the file and close the file descriptor
HRN_STORAGE_REMOVE(hrnStorage, "lock/badpid" LOCK_FILE_EXT);
HRN_STORAGE_REMOVE(hrnStorage, "lock/db-backup" LOCK_FILE_EXT);
close(lockFd);
}
HRN_FORK_CHILD_END();
@ -316,5 +317,47 @@ testRun(void)
HRN_FORK_END();
}
// *****************************************************************************************************************************
if (testBegin("cmdStop(), force, no stanza/stanza"))
{
StringList *argList = strLstNew();
hrnCfgArgRawBool(argList, cfgOptForce, true);
HRN_CFG_LOAD(cfgCmdStop, argList);
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("no stanza, force stop = process all lock files, ignore non lock files");
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-junk.txt", .comment = "create empty non lock file, s/b ignored");
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, " ", .comment = "create backup lock file for stanza");
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-archive" LOCK_FILE_EXT, .comment = "create empty archive lock file for stanza");
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db1-backup" LOCK_FILE_EXT, " ", .comment = "create non-empty lock file other stanza");
TEST_RESULT_VOID(cmdStop(), "no stanza, create stop file, ignore non lock file");
TEST_STORAGE_EXISTS(hrnStorage, "lock/all" STOP_FILE_EXT, .comment = "stanza stop file created");
TEST_STORAGE_LIST(
hrnStorage, "lock", "all" STOP_FILE_EXT "\n" "db-junk.txt\n", .comment = "stop file created, all lock files processed");
TEST_RESULT_LOG("");
HRN_STORAGE_PATH_REMOVE(hrnStorage, "lock", .recurse = true, .errorOnMissing = true, .comment = "remove the lock path");
// -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("stanza, force stop = process only stanza lock files, ignore other stanza lock files and other files");
hrnCfgArgRawZ(argList, cfgOptStanza, "db");
HRN_CFG_LOAD(cfgCmdStop, argList);
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-junk.txt", .comment = "create empty non lock file, s/b ignored");
HRN_STORAGE_PUT_EMPTY(hrnStorage, "lock/db-archive" LOCK_FILE_EXT, .comment = "create stanza empty lock file");
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db1-backup" LOCK_FILE_EXT, " ", .comment = "create other stanza non-empty lock file");
HRN_STORAGE_PUT_Z(hrnStorage, "lock/db-backup" LOCK_FILE_EXT, " ", .comment = "create stanza non-empty lock file");
TEST_RESULT_VOID(cmdStop(), "stanza, create stop file, ignore other stanza lock and other files");
TEST_STORAGE_EXISTS(hrnStorage, "lock/db" STOP_FILE_EXT, .comment = "stanza stop file created");
TEST_STORAGE_LIST(
hrnStorage, "lock", "db-junk.txt\ndb" STOP_FILE_EXT "\n" "db1-backup" LOCK_FILE_EXT "\n",
.comment = "stop file created, stanza lock file was removed, other stanza lock and other files remain");
TEST_RESULT_LOG("");
HRN_STORAGE_PATH_REMOVE(hrnStorage, "lock", .recurse = true, .errorOnMissing = true, .comment = "remove the lock path");
}
FUNCTION_HARNESS_RETURN_VOID();
}