You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-06-14 23:44:58 +02:00
Fix possible truncated WAL segments when an error occurs mid-write.
The file write object destructors called close() and finalized the file even if it was not completely written. This was an issue in both the C and Perl code. Rewrite the destructors to simply free resources (like file handles) rather than calling the close() method. This leaves the temp file in place for filesystems that use temp files. Add unit tests to prevent regression. Reported by blogh.
This commit is contained in:
@ -304,6 +304,20 @@ sub run
|
||||
|
||||
undef($oPosixIo);
|
||||
|
||||
# Test that a premature destroy (from error or otherwise) does not rename the file
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
my $strFileAbort = $self->testPath() . '/file-abort.txt';
|
||||
my $strFileAbortTmp = "${strFileAbort}.tmp";
|
||||
|
||||
$oPosixIo = $self->testResult(
|
||||
sub {new pgBackRest::Storage::Posix::FileWrite($oPosix, $strFileAbort, {bAtomic => true})}, '[object]', 'open');
|
||||
|
||||
$oPosixIo->write(\$strFileContent);
|
||||
undef($oPosixIo);
|
||||
|
||||
$self->testResult(sub {$oPosix->exists($strFileAbort)}, false, 'destination file does not exist');
|
||||
$self->testResult(sub {$oPosix->exists($strFileAbortTmp)}, true, 'destination file tmp exists');
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oPosixIo = $self->testResult(
|
||||
sub {new pgBackRest::Storage::Posix::FileWrite($oPosix, $strFile, {lTimestamp => time()})}, '[object]', 'open');
|
||||
|
@ -193,6 +193,17 @@ sub run
|
||||
$self->testResult(sub {$oFileWrite->write(\$strFileContent)}, $iFileLength, ' write');
|
||||
$oFileWrite->close();
|
||||
|
||||
$self->testResult(sub {$oS3->exists("/path/to/${strFile}" . '.@')}, true, 'destination file exists');
|
||||
|
||||
# Test that a premature destroy (from error or otherwise) does not rename the file
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oFileWrite = $self->testResult(sub {$oS3->openWrite("/path/to/abort.file" . '.@')}, '[object]', 'open write');
|
||||
$self->testResult(sub {$oFileWrite->write()}, 0, ' write undef');
|
||||
$self->testResult(sub {$oFileWrite->write(\$strFileContent)}, $iFileLength, ' write');
|
||||
|
||||
undef($oFileWrite);
|
||||
$self->testResult(sub {$oS3->exists("/path/to/abort.file")}, false, 'destination file does not exist');
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------------------------
|
||||
$oFileWrite = $self->testResult(sub {$oS3->openWrite("/path/to/${strFile}")}, '[object]', 'open write');
|
||||
|
||||
|
Reference in New Issue
Block a user