1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-28 05:36:12 +02:00

Fixed issue #91: Race condition in async archive-push.

This commit is contained in:
David Steele 2015-05-29 16:31:12 -04:00
parent 5fd4f3bd5b
commit e7d2d704fe
5 changed files with 22 additions and 5 deletions

View File

@ -751,6 +751,8 @@ example: db-path=/data/db
* Fixed an issue in async archiving where archive-push was not properly returning 0 when archive-max-mb was reached and moved the async check after transfer to avoid having to remove the stop file twice. Also added unit tests for this case and improved error messages to make it clearer to the user what went wrong. Reported by Michael Renner.
* Fixed a locking issue that could allow multiple operations of the same type against a single stanza. This appeared to be benign in terms of data integrity but caused spurious errors while archiving and could lead to errors in backup/restore. Reported by Michael Renner.
* Replaced JSON module with JSON::PP which ships with core Perl.
### v0.65: Improved resume and restore logging, compact restores

View File

@ -709,6 +709,9 @@ Run a <id>full</id> backup on the <id>db</id> stanza. <param>--type</param> can
<release-feature>
<text>Fixed an issue in async archiving where archive-push was not properly returning 0 when archive-max-mb was reached and moved the async check after transfer to avoid having to remove the stop file twice. Also added unit tests for this case and improved error messages to make it clearer to the user what went wrong. Reported by Michael Renner.</text>
</release-feature>
<release-feature>
<text>Fixed a locking issue that could allow multiple operations of the same type against a single stanza. This appeared to be benign in terms of data integrity but caused spurious errors while archiving and could lead to errors in backup/restore. Reported by Michael Renner.</text>
</release-feature>
<release-feature>
<text>Replaced JSON module with JSON::PP which ships with core Perl.</text>
</release-feature>

View File

@ -385,15 +385,19 @@ sub pushProcess
# Else the no-fork flag has been specified for testing
else
{
&log(INFO, 'No fork on archive local for TESTING');
&log(DEBUG, 'No fork on archive local for TESTING');
}
# Start the async archive push
&log(INFO, 'starting async archive-push');
&log(DEBUG, 'starting async archive-push');
}
# Create a lock file to make sure async archive-push does not run more than once
lockAcquire(operationGet());
if (!lockAcquire(operationGet(), false))
{
&log(DEBUG, 'another async archive-push process is already running - exiting');
return 0;
}
# Open the log file
log_file_set(optionGet(OPTION_REPO_PATH) . '/log/' . optionGet(OPTION_STANZA) . '-archive-async');

View File

@ -38,6 +38,7 @@ use constant
ERROR_PATH_CREATE => 122,
ERROR_OPERATION_INVALID => 123,
ERROR_HOST_CONNECT => 124,
ERROR_LOCK_ACQUIRE => 125,
ERROR_UNKNOWN => 199
};
@ -47,7 +48,7 @@ our @EXPORT = qw(ERROR_ASSERT ERROR_CHECKSUM ERROR_CONFIG ERROR_FILE_INVALID ERR
ERROR_OPTION_DUPLICATE_KEY ERROR_OPTION_NEGATE ERROR_OPTION_REQUIRED ERROR_POSTMASTER_RUNNING ERROR_PROTOCOL
ERROR_RESTORE_PATH_NOT_EMPTY ERROR_FILE_OPEN ERROR_FILE_READ ERROR_PARAM_REQUIRED ERROR_ARCHIVE_MISMATCH
ERROR_ARCHIVE_DUPLICATE ERROR_VERSION_NOT_SUPPORTED ERROR_PATH_CREATE ERROR_OPERATION_INVALID ERROR_HOST_CONNECT
ERROR_UNKNOWN);
ERROR_UNKNOWN ERROR_LOCK_ACQUIRE);
####################################################################################################################################
# CONSTRUCTOR

View File

@ -62,6 +62,7 @@ sub lockFileName
sub lockAcquire
{
my $strLockType = shift;
my $bFailOnNoLock = shift;
# Cannot proceed if a lock is currently held
if (defined($strCurrentLockType))
@ -80,12 +81,18 @@ sub lockAcquire
$strCurrentLockFile = lockFileName($strLockType, optionGet(OPTION_STANZA), optionGet(OPTION_REPO_PATH));
sysopen($hCurrentLockHandle, $strCurrentLockFile, O_WRONLY | O_CREAT)
or confess &log(ERROR, "unable to open lock file ${strCurrentLockFile}");
or confess &log(ERROR, "unable to open lock file ${strCurrentLockFile}", ERROR_FILE_OPEN);
# Attempt to lock the lock file
if (!flock($hCurrentLockHandle, LOCK_EX | LOCK_NB))
{
close($hCurrentLockHandle);
if (!defined($bFailOnNoLock) || $bFailOnNoLock)
{
confess &log(ERROR, "unable to acquire ${strLockType} lock", ERROR_LOCK_ACQUIRE);
}
return false;
}