Skip to content

Commit

Permalink
Fixed an issue where the async archiver would not be started if archi…
Browse files Browse the repository at this point in the history
…ve-push did not have enough space to queue a new WAL segment.

This meant that the queue would never be cleared without manual intervention (such as calling archive-push directly). PostgreSQL now receives errors when there is not enough space to store new WAL segments but the async process will still be started so that space is eventually freed.

Reported by Jens Wilke.
  • Loading branch information
dwsteele committed Oct 5, 2016
1 parent 2a18674 commit 5dc801d
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 3 deletions.
8 changes: 8 additions & 0 deletions doc/xml/release.xml
Expand Up @@ -141,6 +141,14 @@

<p>Fixed error message to properly display the archive command when an invalid archive command is detected.</p>
</release-item>

<release-item>
<release-item-contributor-list>
<release-item-ideator id="wilke.jens"/>
</release-item-contributor-list>

<p>Fixed an issue where the async archiver would not be started if <cmd>archive-push</cmd> did not have enough space to queue a new WAL segment. This meant that the queue would never be cleared without manual intervention (such as calling <cmd>archive-push</cmd> directly). <postgres/> now receives errors when there is not enough space to store new WAL segments but the async process will still be started so that space is eventually freed.</p>
</release-item>
</release-bug-list>

<release-feature-list>
Expand Down
24 changes: 22 additions & 2 deletions lib/pgBackRest/Archive.pm
Expand Up @@ -589,6 +589,8 @@ sub pushProcess
}

# If an archive file is defined, then push it
my $oException = undef;

if (defined($ARGV[1]))
{
# If the stop file exists then discard the archive log
Expand All @@ -606,13 +608,27 @@ sub pushProcess

&log(INFO, 'push WAL segment ' . $ARGV[1] . ($bArchiveAsync ? ' asynchronously' : ''));

$self->push($ARGV[1], $bArchiveAsync);
# Push WAL segment - when async, any error will be deferred until after the async process has been started
eval
{
$self->push($ARGV[1], $bArchiveAsync);
return true;
}
or do
{
$oException = $EVAL_ERROR;

if (!$bArchiveAsync || !optionTest(OPTION_TEST_NO_FORK))
{
confess $oException;
}
};

# Fork if async archiving is enabled
if ($bArchiveAsync)
{
# Fork and disable the async archive flag if this is the parent process
if (!optionTest(OPTION_TEST_NO_FORK) || !optionGet(OPTION_TEST_NO_FORK))
if (!optionTest(OPTION_TEST_NO_FORK))
{
$bArchiveAsync = fork() == 0 ? true : false;
}
Expand Down Expand Up @@ -661,6 +677,10 @@ sub pushProcess
lockRelease();
}
}
elsif (defined($oException))
{
confess $oException;
}

# Return from function and log return values if any
return logDebugReturn
Expand Down
2 changes: 1 addition & 1 deletion lib/pgBackRest/Protocol/IO.pm
Expand Up @@ -490,7 +490,7 @@ sub bufferWrite
my $strError = $!;

$self->waitPid();
confess "unable to write ${iWriteSize} bytes" . (defined($strError) ? ': ' . $strError : '');
confess &log(ERROR, "unable to write ${iWriteSize} bytes" . (defined($strError) ? ': ' . $strError : ''), ERROR_FILE_WRITE);
}
}

Expand Down
4 changes: 4 additions & 0 deletions test/expect/backup-archive-push-002.log
Expand Up @@ -175,6 +175,10 @@ P00 DEBUG: Protocol::Protocol::protocolGet(): iRemoteIdx = <1>, oParam = [u
P00 DEBUG: Protocol::Protocol::protocolGet: create local protocol
P00 DEBUG: File->new(): oProtocol = [object], strBackupPath = [TEST_PATH]/db-master/repo, strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strStanza = db
P00 ERROR: [137]: stop file exists for all stanzas
P00 DEBUG: Archive->pushProcess: no fork on archive local for TESTING
P00 DEBUG: Archive->pushProcess: start async archive-push
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = false, bRemote = <false>, iProcessIdx = [undef], strLockType = archive-push
P00 ERROR: [137]: stop file exists for all stanzas
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = [undef], oException = [object], strSignal = [undef]
P00 INFO: archive-push stop
P00 DEBUG: Protocol::Protocol::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef]
Expand Down
4 changes: 4 additions & 0 deletions test/expect/backup-archive-push-006.log
Expand Up @@ -181,6 +181,10 @@ P00 DEBUG: Protocol::Protocol::protocolGet(): iRemoteIdx = <1>, oParam = [u
P00 DEBUG: Protocol::Protocol::protocolGet: create local protocol
P00 DEBUG: File->new(): oProtocol = [object], strBackupPath = [TEST_PATH]/db-master/spool, strDefaultFileMode = <0640>, strDefaultPathMode = <0750>, strStanza = db
P00 ERROR: [137]: stop file exists for all stanzas
P00 DEBUG: Archive->pushProcess: no fork on archive local for TESTING
P00 DEBUG: Archive->pushProcess: start async archive-push
P00 DEBUG: Common::Lock::lockAcquire(): bFailOnNoLock = false, bRemote = <false>, iProcessIdx = [undef], strLockType = archive-push
P00 ERROR: [137]: stop file exists for all stanzas
P00 DEBUG: Common::Exit::exitSafe(): iExitCode = [undef], oException = [object], strSignal = [undef]
P00 INFO: archive-push stop
P00 DEBUG: Protocol::Protocol::protocolDestroy(): bComplete = false, iRemoteIdx = [undef], strRemoteType = [undef]
Expand Down

0 comments on commit 5dc801d

Please sign in to comment.