SQL Server的SMO - Backuping - 如何判断故障/成功呢?如何判断、故障、Server、SQL

2023-09-06 18:18:18 作者:平凡之路

如果您使用SMO执行备份,成功完成后,我测试了SQLERROR为空,考虑到备份完成且无错:

If you execute backup using SMO, after successful completion, I test the SqlError for null, considering that the backup completed without errors:

但是,正如你所看到的,它实际上返回类的错误0号3014意味着成功。

But, as you can see, it actually return an error of class 0 number 3014 meaning success.

所以,问题是:

问:我如何才能知道是否备份成功或没有完成,我应该如何处理这些消息和状态干净

我怕有多个陷阱在这里,我不想咬我的屁股后,当这code去生产:)

I'm afraid that there are multiple of "gotchas" here that I don't want to bite me in the ass later when this code goes production :)

推荐答案

我同意有多个陷阱,我个人认为微软SMO事件执行不力的ServerMessageEventArgs包含属性错误而并不总是提供有关错误信息但消息关于成功的行动!

I agree there are multiple "gotchas" and I personally think Microsoft SMO events are poorly implemented as the ServerMessageEventArgs contains a Property Error which not always provides information about an error but messages about successful operations!!

作为一个例子: 在与code 4035错误是一个信息消息。不是一个错误。 在与code 3014错误是发生在成功完成一条信息。不是一个错误

As an example: The "error" with code 4035 is an information message. Not an error. The "error" with code 3014 is an information message that happens when completed successfully. Not an error

另请注意,发生错误时的信息事件并不经常发生。它实际发生时SQL Server发送一条消息,可能是关于已成功完成操作的信息

Also notice that the Information event does not always happen when an error has occurred. It actually happens whenever SQL Server sends a message that could be information about the operation that has finished successfully

我也担心不处理的错误/成功的正确,但检查SQLERROR为Null是一个坏主意,因为它不会永远空,这总是会包含有关成功运作或某些消息一个错误。和假设信息事件发生时,有一个错误,也是一个不错的主意

I am also concerned about not handling the errors/success properly, but checking sqlError as Null is a bad idea since it will not be ever null and it will always contain some message about successful operation or an error. And assuming that Information event occurs when there is an error is also a bad idea.

我建议来处理通过SqlError.Number错误并根据SMO事件已被触发。

I suggest to handle the errors through the SqlError.Number and depending on the SMO event it has been triggered.

我已经做了以下code创建一个数据库备份。它是在VB.NET但在C#将是相似的。它接收必要的参数,包括委托的地方调用事件(以GUI处理),进度报告百分比和错误处理取决于事件触发,并提到SqlError.Number为

I have made the following code to create a database backup. It is in VB.NET but in C# would be similar. It receives necessary parameters including a delegate where to invoke events (to be handled at GUI), a progress to report the percentage and error handling depending on event triggered and the SqlError.Number as mentioned

Public Sub BackupDatabase(databaseName As String, backupFileFullPath As String, optionsBackup As OptionsBackupDatabase, operationProgress As IProgress(Of Integer),
                          operationResult As Action(Of OperationResult)) Implements IDatabaseManager.BackupDatabase
    Dim sqlBackup As New Smo.Backup()
    sqlBackup.Action = Smo.BackupActionType.Database
    sqlBackup.BackupSetName = databaseName & " Backup"
    sqlBackup.BackupSetDescription = "Full Backup of " & databaseName
    sqlBackup.Database = databaseName
    Dim bkDevice As New Smo.BackupDeviceItem(backupFileFullPath, Smo.DeviceType.File)
    sqlBackup.Devices.Add(bkDevice)
    sqlBackup.Initialize = optionsBackup.Overwrite
    sqlBackup.Initialize = True
    sqlBackup.PercentCompleteNotification = 5

    AddHandler sqlBackup.PercentComplete, Sub(sender As Object, e As PercentCompleteEventArgs)
                                              operationProgress.Report(e.Percent)
                                          End Sub
    AddHandler sqlBackup.Complete, Sub(sender As Object, e As ServerMessageEventArgs)
                                       Dim sqlMessage As SqlClient.SqlError = e.Error
                                       Dim opResult As New OperationResult()
                                       Select Case sqlMessage.Number
                                           Case 3014
                                               opResult.operationResultType = OperationResultType.SmoSuccess
                                               opResult.message = "Backup successfully created at " & backupFileFullPath & ". " & sqlMessage.Number & ": " & sqlMessage.Message
                                           Case Else
                                               opResult.operationResultType = OperationResultType.SmoError
                                               opResult.message = "ERROR CODE " & sqlMessage.Number & ": " & sqlMessage.Message
                                       End Select
                                       operationResult.Invoke(opResult)
                                   End Sub

    AddHandler sqlBackup.NextMedia, Sub(sender As Object, e As ServerMessageEventArgs)
                                        Dim sqlMessage As SqlClient.SqlError = e.Error
                                        Dim opResult As New OperationResult()
                                        opResult.operationResultType = OperationResultType.SmoError
                                        opResult.message = "ERROR CODE:  " & sqlMessage.Number & ": " & sqlMessage.Message
                                        operationResult.Invoke(opResult)
                                    End Sub

    AddHandler sqlBackup.Information, Sub(sender As Object, e As ServerMessageEventArgs)
                                          Dim sqlMessage As SqlClient.SqlError = e.Error
                                          Dim opResult As New OperationResult()
                                          Select Case sqlMessage.Number
                                              Case 4035
                                                  opResult.operationResultType = OperationResultType.SmoInformation
                                                  opResult.message = sqlMessage.Number & ": " & sqlMessage.Message
                                              Case Else
                                                  opResult.operationResultType = OperationResultType.SmoError
                                                  opResult.message = "ERROR CODE " & sqlMessage.Number & ": " & sqlMessage.Message
                                          End Select
                                          operationResult.Invoke(opResult)
                                      End Sub
    Try
        sqlBackup.SqlBackupAsync(smoServer)
    Catch ex As Exception
        Throw New BackupManagerException("Error backing up database " & databaseName, ex)
    End Try
End Sub