Skip to content

Commit

Permalink
Merge pull request #6 from LuccaSA/dbcc.checkdb
Browse files Browse the repository at this point in the history
adds dbcc checkdb option
  • Loading branch information
rducom committed Aug 1, 2021
2 parents 69631c5 + 3475fbd commit cc5a6fa
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 9 deletions.
16 changes: 16 additions & 0 deletions src/SqlBackupTools/Notification/SlackSend.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,22 @@ public async Task ReportAsync(ReportState state, string slackChannel, string sla
});
}

if (state.IntegrityErrors.Any())
{
subMsg.Attachments.Add(new Attachment
{
Color = AlertLevel.Error.ToSlackColor(),
Title = $"DBCC CHECKDB Error :",
Fields = state.IntegrityErrors
.Select(i => new Field
{
Title = i.Key + " :",
Value = string.Join(Environment.NewLine, i.Value),
Short = false
}).ToArray()
});
}

await _slackClient.SendSlackMessageAsync(subMsg, slackSecret);
}

Expand Down
29 changes: 29 additions & 0 deletions src/SqlBackupTools/Restore/DbccCheckDbResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace SqlBackupTools.Restore
{
public class DbccCheckDbResult
{
public int Error { get; set; }
public int Level { get; set; }
public int State { get; set; }
public string MessageText { get; set; }
public int RepairLevel { get; set; }
public int Status { get; set; }
public int DbId { get; set; }
public int DbFragId { get; set; }
public int ObjectId { get; set; }
public int IndexId { get; set; }
public int PartitionID { get; set; }
public int AllocUnitID { get; set; }
public int RidDbId { get; set; }
public int RidPruId { get; set; }
public int File { get; set; }
public int Page { get; set; }
public int Slot { get; set; }
public int RefDbId { get; set; }
public int RefPruId { get; set; }
public int RefFile { get; set; }
public int RefPage { get; set; }
public int RefSlot { get; set; }
public int Allocation { get; set; }
}
}
2 changes: 2 additions & 0 deletions src/SqlBackupTools/Restore/RestoreCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,7 @@ public bool IsUncheckedModeEnable
}
}

[Option("checkDb", HelpText = "runs DBCC CHECKDB")]
public bool CheckDb { get; set; }
}
}
44 changes: 36 additions & 8 deletions src/SqlBackupTools/Restore/RestoreRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ private static async Task<RestoreItem> RestoreBackupAsync(IRestoreMethod restore

try
{
Exception scriptException = null;

if (restoreCommand.RunRecovery)
{
var recoveryException = await restoreMethod.RunRecoveryAsync(item);
Expand All @@ -107,13 +109,10 @@ private static async Task<RestoreItem> RestoreBackupAsync(IRestoreMethod restore
item.SetError(recoveryException);
throw recoveryException;
}
}

Exception scriptException = null;
if (restoreCommand.RunRecovery)
{
await using var sqlConnectionOnDatabase = restoreCommand.CreateConnectionMars(item.Name);
scriptException = await PostScriptExecuteAsync(state, sqlConnectionOnDatabase, item);
scriptException = await PostScriptExecuteAsync(state, item);

await RunDbccCheckDb(state, item);
}

if (scriptException != null)
Expand Down Expand Up @@ -159,6 +158,33 @@ private static async Task<RestoreItem> RestoreBackupAsync(IRestoreMethod restore
return item;
}

private static async Task RunDbccCheckDb(RestoreState state, RestoreItem item)
{
if (state.RestoreCommand.CheckDb == false)
{
return;
}

await using var sqlConnectionOnDatabase = state.RestoreCommand.CreateConnectionMars(item.Name);
try
{

var checkdbResults = await sqlConnectionOnDatabase.QueryAsync<DbccCheckDbResult>("DBCC CHECKDB with TABLERESULTS", commandTimeout: state.RestoreCommand.Timeout);

foreach (var r in checkdbResults.Where(i => i.Level >= 17))
{
state.Loggger.Fatal($"[{item.Name}] Error found while DBCC CHECKDB : " + r.MessageText);
var errors = state.IntegrityErrors.GetValueOrDefault(item.Name, new List<string>());
errors.Add(r.MessageText);
}
}
catch (Exception e)
{
state.Loggger.Error(e, $"[{item.Name}] Error while DBCC CHECKDB");
return;
}
}

private static bool StartFromFull(RestoreState state, RestoreItem item)
{
if (!state.ActualDbs.ContainsKey(item.Name))
Expand All @@ -178,7 +204,7 @@ private static bool StartFromFull(RestoreState state, RestoreItem item)
return false;
}

private static async Task<Exception> PostScriptExecuteAsync(RestoreState state, SqlConnection sqlConnection, RestoreItem restoreItem)
private static async Task<Exception> PostScriptExecuteAsync(RestoreState state, RestoreItem restoreItem)
{
if (state.RestoreCommand.PostScripts == null)
{
Expand All @@ -203,9 +229,11 @@ private static async Task<Exception> PostScriptExecuteAsync(RestoreState state,
{
var scripts = LoadScripts(state.RestoreCommand);
state.Loggger.Debug("Applying " + scripts.Count + " sql scripts");
await using var sqlConnectionOnDatabase = state.RestoreCommand.CreateConnectionMars(restoreItem.Name);

foreach (var script in scripts)
{
await sqlConnection.ExecuteAsync(script, commandTimeout: state.RestoreCommand.Timeout);
await sqlConnectionOnDatabase.ExecuteAsync(script, commandTimeout: state.RestoreCommand.Timeout);
}
}
catch (Exception e)
Expand Down
9 changes: 8 additions & 1 deletion src/SqlBackupTools/Restore/RestoreState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class ReportState
public ReportStatus Status { get; internal set; } = ReportStatus.Ok;
public ServerInfos Info { get; internal set; }
public string Mode { get; internal set; }
public Dictionary<string, List<string>> IntegrityErrors { get; } = new Dictionary<string, List<string>>();
}

[Flags]
Expand Down Expand Up @@ -70,7 +71,7 @@ public RestoreState(ILogger logger, RestoreCommand restoreCommand, SqlConnection
public TimeSpan Accumulated { get; set; }
public ServerInfos ServerInfos { get; set; }
public List<(string name, int count, List<DirectoryInfo> excluded)> DuplicatesExcluded { get; } = new List<(string name, int count, List<DirectoryInfo> excluded)>();

public Dictionary<string, List<string>> IntegrityErrors { get; } = new Dictionary<string, List<string>>();
private readonly Stopwatch _sw = new Stopwatch();
private int _increment = 0;

Expand Down Expand Up @@ -187,6 +188,12 @@ public async Task<ReportState> GetReportStateAsync()
}
}
}

foreach(var i in IntegrityErrors)
{
reportState.IntegrityErrors.Add(i.Key,i.Value);
}

return reportState;
}

Expand Down

0 comments on commit cc5a6fa

Please sign in to comment.