You've already forked pgbackrest
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:
@ -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>
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Reference in New Issue
Block a user