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

Add hint to check the log on archive-get/archive-push async error.

If this error is thrown rather than a specific error returned from the async process, it means the async process is unable to write the status files for some reason and the only way to get the error is out of the async log.

This hint includes the exact async log path and name to make finding errors easier.
This commit is contained in:
David Steele
2022-05-02 08:49:13 -04:00
parent 126fc99c77
commit 03c71aa606
7 changed files with 73 additions and 36 deletions

View File

@ -116,6 +116,17 @@
<p>Improve error message for invalid <br-option>repo-azure-key</br-option>.</p> <p>Improve error message for invalid <br-option>repo-azure-key</br-option>.</p>
</release-item> </release-item>
<release-item>
<github-issue id="1722"/>
<release-item-contributor-list>
<release-item-contributor id="david.steele"/>
<release-item-reviewer id="reid.thompson"/>
</release-item-contributor-list>
<p>Add hint to check the log on <cmd>archive-get</cmd>/<cmd>archive-push</cmd> async error.</p>
</release-item>
</release-improvement-list> </release-improvement-list>
<release-development-list> <release-development-list>

View File

@ -20,6 +20,7 @@ Archive Get Command
#include "common/wait.h" #include "common/wait.h"
#include "config/config.h" #include "config/config.h"
#include "config/exec.h" #include "config/exec.h"
#include "config/load.h"
#include "info/infoArchive.h" #include "info/infoArchive.h"
#include "postgres/interface.h" #include "postgres/interface.h"
#include "protocol/helper.h" #include "protocol/helper.h"
@ -776,8 +777,11 @@ cmdArchiveGet(void)
if (!foundOk) if (!foundOk)
{ {
THROW_FMT( THROW_FMT(
ArchiveTimeoutError, "unable to get WAL file '%s' from the archive asynchronously after %s second(s)", ArchiveTimeoutError,
strZ(walSegment), strZ(strNewDbl((double)cfgOptionInt64(cfgOptArchiveTimeout) / MSEC_PER_SEC))); "unable to get WAL file '%s' from the archive asynchronously after %s second(s)\n"
"HINT: check '%s' for errors.",
strZ(walSegment), strZ(strNewDbl((double)cfgOptionInt64(cfgOptArchiveTimeout) / MSEC_PER_SEC)),
strZ(cfgLoadLogFileName(cfgCmdRoleAsync)));
} }
// Else report that the WAL segment could not be found // Else report that the WAL segment could not be found
else else

View File

@ -17,6 +17,7 @@ Archive Push Command
#include "common/memContext.h" #include "common/memContext.h"
#include "common/wait.h" #include "common/wait.h"
#include "config/config.h" #include "config/config.h"
#include "config/load.h"
#include "config/exec.h" #include "config/exec.h"
#include "info/infoArchive.h" #include "info/infoArchive.h"
#include "postgres/interface.h" #include "postgres/interface.h"
@ -393,8 +394,10 @@ cmdArchivePush(void)
if (!pushed) if (!pushed)
{ {
THROW_FMT( THROW_FMT(
ArchiveTimeoutError, "unable to push WAL file '%s' to the archive asynchronously after %s second(s)", ArchiveTimeoutError,
strZ(archiveFile), strZ(cfgOptionDisplay(cfgOptArchiveTimeout))); "unable to push WAL file '%s' to the archive asynchronously after %s second(s)\n"
"HINT: check '%s' for errors.",
strZ(archiveFile), strZ(cfgOptionDisplay(cfgOptArchiveTimeout)), strZ(cfgLoadLogFileName(cfgCmdRoleAsync)));
} }
// Log success // Log success

View File

@ -354,6 +354,42 @@ cfgLoadUpdateOption(void)
FUNCTION_LOG_RETURN_VOID(); FUNCTION_LOG_RETURN_VOID();
} }
/**********************************************************************************************************************************/
String *
cfgLoadLogFileName(const ConfigCommandRole commandRole)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(ENUM, commandRole);
FUNCTION_LOG_END();
// Construct log filename prefix
String *const result = strCatFmt(
strNew(),
"%s/%s-%s", strZ(cfgOptionStr(cfgOptLogPath)),
cfgOptionTest(cfgOptStanza) ? strZ(cfgOptionStr(cfgOptStanza)): "all", cfgCommandName());
// ??? Append async for local/remote archive async commands. It would be good to find a more generic way to do this in case the
// async role is added to more commands.
if (commandRole == cfgCmdRoleLocal || commandRole == cfgCmdRoleRemote)
{
if (cfgOptionValid(cfgOptArchiveAsync) && cfgOptionBool(cfgOptArchiveAsync))
strCatZ(result, "-async");
}
// Add command role if it is not main
if (commandRole != cfgCmdRoleMain)
strCatFmt(result, "-%s", strZ(cfgParseCommandRoleStr(commandRole)));
// Add process id if local or remote role
if (commandRole == cfgCmdRoleLocal || commandRole == cfgCmdRoleRemote)
strCatFmt(result, "-%03u", cfgOptionUInt(cfgOptProcess));
// Add extension
strCatZ(result, ".log");
FUNCTION_LOG_RETURN(STRING, result);
}
/**********************************************************************************************************************************/ /**********************************************************************************************************************************/
void void
cfgLoadLogFile(void) cfgLoadLogFile(void)
@ -362,33 +398,8 @@ cfgLoadLogFile(void)
{ {
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
// Construct log filename prefix
String *logFile = strCatFmt(
strNew(),
"%s/%s-%s", strZ(cfgOptionStr(cfgOptLogPath)),
cfgOptionTest(cfgOptStanza) ? strZ(cfgOptionStr(cfgOptStanza)): "all", cfgCommandName());
// ??? Append async for local/remote archive async commands. It would be good to find a more generic way to do this in
// case the async role is added to more commands.
if (cfgCommandRole() == cfgCmdRoleLocal || cfgCommandRole() == cfgCmdRoleRemote)
{
if (cfgOptionValid(cfgOptArchiveAsync) && cfgOptionBool(cfgOptArchiveAsync))
strCatZ(logFile, "-async");
}
// Add command role if it is not main
if (cfgCommandRole() != cfgCmdRoleMain)
strCatFmt(logFile, "-%s", strZ(cfgParseCommandRoleStr(cfgCommandRole())));
// Add process id if local or remote role
if (cfgCommandRole() == cfgCmdRoleLocal || cfgCommandRole() == cfgCmdRoleRemote)
strCatFmt(logFile, "-%03u", cfgOptionUInt(cfgOptProcess));
// Add extension
strCatZ(logFile, ".log");
// Attempt to open log file // Attempt to open log file
if (!logFileSet(strZ(logFile))) if (!logFileSet(strZ(cfgLoadLogFileName(cfgCommandRole()))))
cfgOptionSet(cfgOptLogLevelFile, cfgSourceParam, VARUINT64(CFGOPTVAL_LOG_LEVEL_CONSOLE_OFF)); cfgOptionSet(cfgOptLogLevelFile, cfgSourceParam, VARUINT64(CFGOPTVAL_LOG_LEVEL_CONSOLE_OFF));
} }
MEM_CONTEXT_TEMP_END(); MEM_CONTEXT_TEMP_END();

View File

@ -6,7 +6,7 @@ Configuration Load
#include <sys/types.h> #include <sys/types.h>
#include "common/type/string.h" #include "config/config.h"
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Functions Functions
@ -14,6 +14,9 @@ Functions
// Load the configuration // Load the configuration
void cfgLoad(unsigned int argListSize, const char *argList[]); void cfgLoad(unsigned int argListSize, const char *argList[]);
// Generate log file path and name. Only the command role is configurable here because log settings may vary between commands.
String *cfgLoadLogFileName(ConfigCommandRole commandRole);
// Attempt to set the log file and turn file logging off if the file cannot be opened // Attempt to set the log file and turn file logging off if the file cannot be opened
void cfgLoadLogFile(void); void cfgLoadLogFile(void);

View File

@ -679,7 +679,8 @@ testRun(void)
TEST_ERROR( TEST_ERROR(
cmdArchiveGet(), ArchiveTimeoutError, cmdArchiveGet(), ArchiveTimeoutError,
"unable to get WAL file '000000010000000100000001' from the archive asynchronously after 1 second(s)"); "unable to get WAL file '000000010000000100000001' from the archive asynchronously after 1 second(s)\n"
"HINT: check '" HRN_PATH "/test1-archive-get-async.log' for errors.");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("check for missing WAL"); TEST_TITLE("check for missing WAL");
@ -688,7 +689,8 @@ testRun(void)
TEST_ERROR( TEST_ERROR(
cmdArchiveGet(), ArchiveTimeoutError, cmdArchiveGet(), ArchiveTimeoutError,
"unable to get WAL file '000000010000000100000001' from the archive asynchronously after 1 second(s)"); "unable to get WAL file '000000010000000100000001' from the archive asynchronously after 1 second(s)\n"
"HINT: check '" HRN_PATH "/test1-archive-get-async.log' for errors.");
TEST_RESULT_BOOL( TEST_RESULT_BOOL(
storageExistsP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.ok")), false, storageExistsP(storageSpool(), STRDEF(STORAGE_SPOOL_ARCHIVE_IN "/000000010000000100000001.ok")), false,
@ -758,7 +760,8 @@ testRun(void)
TEST_ERROR( TEST_ERROR(
cmdArchiveGet(), ArchiveTimeoutError, cmdArchiveGet(), ArchiveTimeoutError,
"unable to get WAL file '000000010000000100000001' from the archive asynchronously after 1 second(s)"); "unable to get WAL file '000000010000000100000001' from the archive asynchronously after 1 second(s)\n"
"HINT: check '" HRN_PATH "/test1-archive-get-async.log' for errors.");
// Notify child to release lock // Notify child to release lock
HRN_FORK_PARENT_NOTIFY_PUT(0); HRN_FORK_PARENT_NOTIFY_PUT(0);

View File

@ -654,7 +654,8 @@ testRun(void)
TEST_ERROR( TEST_ERROR(
cmdArchivePush(), ArchiveTimeoutError, cmdArchivePush(), ArchiveTimeoutError,
"unable to push WAL file 'bogus' to the archive asynchronously after 1 second(s)"); "unable to push WAL file 'bogus' to the archive asynchronously after 1 second(s)\n"
"HINT: check '" HRN_PATH "/test-archive-push-async.log' for errors.");
// Create pg_control and archive.info for next set of tests // Create pg_control and archive.info for next set of tests
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
@ -728,7 +729,8 @@ testRun(void)
TEST_ERROR( TEST_ERROR(
cmdArchivePush(), ArchiveTimeoutError, cmdArchivePush(), ArchiveTimeoutError,
"unable to push WAL file '000000010000000100000001' to the archive asynchronously after 1 second(s)"); "unable to push WAL file '000000010000000100000001' to the archive asynchronously after 1 second(s)\n"
"HINT: check '" HRN_PATH "/test-archive-push-async.log' for errors.");
// Notify child to release lock // Notify child to release lock
HRN_FORK_PARENT_NOTIFY_PUT(0); HRN_FORK_PARENT_NOTIFY_PUT(0);