diff --git a/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs b/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs index c415aa787..1a5beade0 100644 --- a/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs +++ b/Duplicati/Library/Main/Database/LocalRestoreDatabase.cs @@ -667,8 +667,8 @@ namespace Duplicati.Library.Main.Database // An optimal algorithm would build a depency net with cycle resolution to find the best near topological // order of volumes, but this is a bit too fancy here. // We will just put a very simlpe heuristic to work, that will try to prefer volumes containing lower block indexes: - // We just order all volumes by the maximum block index they contain. - // That is likely to restore all files from front to back. Large files will always be done last. + // We just order all volumes by the maximum block index they contain. This query is slow, but should be worth the effort. + // Now it is likely to restore all files from front to back. Large files will always be done last. // One could also use like the average block number in a volume, that needs to be measured. cmd.CommandText = string.Format( @@ -676,9 +676,9 @@ namespace Duplicati.Library.Main.Database + @" FROM ""RemoteVolume"" ""RV"" INNER JOIN " + @" (SELECT ""B"".""VolumeID"", MAX(""TB"".""Index"") as ""MaxIndex"" " + @" FROM ""Block"" ""B"", ""{0}"" ""TB"" " - + @" WHERE ""B"".""Hash"" = ""TB"".""Hash"" " + + @" WHERE ""TB"".""Restored"" = 0 " + + @" AND ""B"".""Hash"" = ""TB"".""Hash"" " + @" AND ""B"".""Size"" = ""TB"".""Size"" " - + @" AND ""TB"".""Restored"" = 0 " + @" GROUP BY ""B"".""VolumeID"" " + @" ) as ""BB"" ON ""RV"".""ID"" = ""BB"".""VolumeID"" " + @" ORDER BY ""BB"".""MaxIndex"" " diff --git a/Duplicati/Library/Main/Operation/RestoreHandler.cs b/Duplicati/Library/Main/Operation/RestoreHandler.cs index 05b308d78..166151140 100644 --- a/Duplicati/Library/Main/Operation/RestoreHandler.cs +++ b/Duplicati/Library/Main/Operation/RestoreHandler.cs @@ -439,27 +439,29 @@ namespace Duplicati.Library.Main.Operation } // Enforce the length of restored files - foreach(var file in database.GetFilesToRestore()) - { - try + // This might be integrated in block restore process when verification is triggered per file on complete + using (new Logging.Timer("Adjusting final file lengths")) + foreach (var file in database.GetFilesToRestore()) { - if (m_result.TaskControlRendevouz() == TaskControlState.Stop) + try { - backend.WaitForComplete(database, null); - return; - } + if (m_result.TaskControlRendevouz() == TaskControlState.Stop) + { + backend.WaitForComplete(database, null); + return; + } - // Fix the length - using(var fs = m_systemIO.FileOpenWrite(file.Path)) - fs.SetLength(file.Length); + // Fix the length + using (var fs = m_systemIO.FileOpenWrite(file.Path)) + fs.SetLength(file.Length); + } + catch (Exception ex) + { + result.AddWarning(ex.Message, ex); + if (ex is System.Threading.ThreadAbortException) + throw; + } } - catch (Exception ex) - { - result.AddWarning(ex.Message, ex); - if (ex is System.Threading.ThreadAbortException) - throw; - } - } // Apply metadata if (!m_options.SkipMetadata)