From e371c664be3b8844504947f5ef4f7cbc8cb59776 Mon Sep 17 00:00:00 2001 From: Kevin Brochet Date: Wed, 1 Oct 2025 16:42:47 +0200 Subject: [PATCH] fix loop trn missing --- .../Restore/Native/NativeRestoreMethod.cs | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/SqlBackupTools/Restore/Native/NativeRestoreMethod.cs b/src/SqlBackupTools/Restore/Native/NativeRestoreMethod.cs index 2a36400..f475aed 100644 --- a/src/SqlBackupTools/Restore/Native/NativeRestoreMethod.cs +++ b/src/SqlBackupTools/Restore/Native/NativeRestoreMethod.cs @@ -215,10 +215,7 @@ private async Task RestoreLogAsync(RestoreItem item, FileInfo lastRestored, SqlC _state.Loggger.Debug("Scraping TRN files from " + restoreLogsFrom); var backupLogsToRestore = new Stack<(FileInfo logFile, RetryStrategy retry)>(); - foreach (var logFileInfo in item.Log - .EnumerateFiles("*.trn", SearchOption.TopDirectoryOnly) - .Where(l => l.BackupDate() > restoreLogsFrom) - .OrderByDescending(l => l.BackupDate())) + foreach (var logFileInfo in ListTrnFromDisk(item, restoreLogsFrom)) { backupLogsToRestore.Push((logFileInfo, RetryStrategy.None)); } @@ -229,6 +226,7 @@ private async Task RestoreLogAsync(RestoreItem item, FileInfo lastRestored, SqlC _state.Loggger.Debug(backupLogsToRestore.Count + " trn files to restore"); int retryCountUsedFile = 3; + int retryMissingTrn = 3; while (backupLogsToRestore.Count != 0) { var (currentLogFile, retryStrategy) = backupLogsToRestore.Pop(); @@ -268,6 +266,7 @@ private async Task RestoreLogAsync(RestoreItem item, FileInfo lastRestored, SqlC } await Task.Delay(10_000); // 10s backupLogsToRestore.Push((currentLogFile, RetryStrategy.None)); + continue; } catch (SqlException sqle) when (sqle.Number == 4326) @@ -278,6 +277,12 @@ private async Task RestoreLogAsync(RestoreItem item, FileInfo lastRestored, SqlC catch (SqlException sqle) when (sqle.Number == 4305) { + if (retryMissingTrn-- == 0) + { + throw; + } + await Task.Delay(10_000); // 10s + //The log in this backup set begins at LSN x, which is too recent to apply to the database. An earlier log backup that includes LSN x can be restored. // - retrying the last log with extract from HeaderOnly @@ -287,8 +292,15 @@ private async Task RestoreLogAsync(RestoreItem item, FileInfo lastRestored, SqlC var ex = await DropDatabaseWhileTryingRestore(item, sqlConnection); throw new BackupRestoreException("The log in this backup set begins at LSN x, which is too recent to apply to the database. We're dropping the DB, and will try restore full on next loop.", ex); } - backupLogsToRestore.Push((currentLogFile, RetryStrategy.None)); + + backupLogsToRestore.Clear(); + IOrderedEnumerable logFilesInfo = ListTrnFromDisk(item, lastLogFile.BackupDate()); + foreach (var logFileInfo in logFilesInfo) + { + backupLogsToRestore.Push((logFileInfo, RetryStrategy.None)); + } backupLogsToRestore.Push((lastLogFile, RetryStrategy.ExtractHeaders)); + continue; } lastLogFile = currentLogFile; @@ -310,6 +322,14 @@ private async Task RestoreLogAsync(RestoreItem item, FileInfo lastRestored, SqlC } } + private static IOrderedEnumerable ListTrnFromDisk(RestoreItem item, DateTime restoreLogsFrom) + { + return item.Log + .EnumerateFiles("*.trn", SearchOption.TopDirectoryOnly) + .Where(l => l.BackupDate() > restoreLogsFrom) + .OrderByDescending(l => l.BackupDate()); + } + private async Task RestoreFullSqlCommandAsync(RestoreItem item, bool modeFileList, SqlConnection sqlConnection, FileInfo fullFile) {