diff --git a/doc/xml/release.xml b/doc/xml/release.xml
index 868582d50..0e916d32e 100644
--- a/doc/xml/release.xml
+++ b/doc/xml/release.xml
@@ -32,6 +32,10 @@
Fix archive-copy throwing path not found
error for incr/diff backups.
+
+ Fix delta restore failing when a linked file was missing.
+
+
diff --git a/lib/pgBackRest/RestoreFile.pm b/lib/pgBackRest/RestoreFile.pm
index a6fa14df5..1c08a3c5d 100644
--- a/lib/pgBackRest/RestoreFile.pm
+++ b/lib/pgBackRest/RestoreFile.pm
@@ -9,6 +9,7 @@ use Carp qw(confess);
use Exporter qw(import);
our @EXPORT = qw();
+use Fcntl qw(:mode);
use File::Basename qw(dirname);
use File::stat qw(lstat);
@@ -77,6 +78,7 @@ sub restoreFile
my $oStorageDb = storageDb();
my $bCopy = true;
+ # Zero file if requested
if ($bZero)
{
$bCopy = false;
@@ -90,16 +92,20 @@ sub restoreFile
$oDestinationFileIo->close();
}
- elsif ($oStorageDb->exists($strDbFile))
+ # Perform delta if requested
+ elsif ($bDelta)
{
- # Perform delta if requested
- if ($bDelta)
+ my $oStat = $oStorageDb->info($strDbFile, {bIgnoreMissing => true});
+
+ # Do the delta if the file exists and is not a link or the link destination exists
+ if (defined($oStat) &&
+ (!S_ISLNK($oStat->mode) ||
+ $oStorageDb->exists(
+ $oStorageDb->pathAbsolute(dirname($strDbFile), $oStorageDb->{oDriver}->linkDestination($strDbFile)))))
{
# If force then use size/timestamp delta
if ($bForce)
{
- my $oStat = lstat($strDbFile);
-
# Make sure that timestamp/size are equal and that timestamp is before the copy start time of the backup
if (defined($oStat) && $oStat->size == $lSize &&
$oStat->mtime == $lModificationTime && $oStat->mtime < $lCopyTimeStart)