2

おおよそ 100 回に 1 回しか発生しない奇妙な問題があります。SQL の SMO ライブラリを使用してデータベースのバックアップを行う PowerShell スクリプトがあります。問題のトラブルシューティングに使用している関連コードの抜粋を次に示します。

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | out-null
$now = get-date
########################################
$server = new-object Microsoft.SqlServer.Management.Smo.Server
$server.ConnectionContext.StatementTimeout = 86400 # Allow backups to take up to 24 hours per database
$databases = $server.Databases
$script:totalsteps = $databases.count
########################################
if($script:totalsteps -eq $null -or $script:totalsteps -eq 0) {
    $body = "Backup start:" +  $now.tostring("yyyy-MM-dd hh:mm:ss tt") + "`r`n" + 
        "Error: " + (get-date).tostring("yyyy-MM-dd hh:mm:ss tt") + "`r`n" + 
        "`$script:totalsteps: " + $script:totalsteps + "`r`n" + 
        "`$databases.count: " + $databases.count + "`r`n" + 
        "`$databases: " + $databases + "`r`n" + 
        "`$server: " + $server
    send-mailmessage -from "me@example.com" -to "me@example.com" -subject "Server Null: $server" -smtpserver "mail.example.com" -body $body
}

問題は、if ステートメントが true と評価されることがあり、次のようなメールが届くことです。

Backup start: 2013-04-30 07:50:58 AM
Error: 2013-04-30 08:02:19 AM
$script:totalsteps: 
$databases.count: 4
$databases: [master] [model] [msdb] [tempdb]
$server: [serverA]

注目すべきは、スクリプトの開始時間とエラー時間の差が約 11 分であるということです。これはやや奇妙です。私の唯一の推測は、サーバーに大きなストレスがかかっているため、PowerShell が黙って変数の割り当てに失敗し、先に進むということです。

100 回中 99 回の if ステートメントが false で、メールが届きません。$script:totalsteps割り当てが 100% の確率で機能しない理由がわかりません。何か案は?これをトラブルシューティングするために他にできることはありますか?

アップデート

遅延評価理論をテストするために、コードを次のように変更しました。

System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | out-null
$now = get-date
########################################
$server = new-object Microsoft.SqlServer.Management.Smo.Server
$server.ConnectionContext.StatementTimeout = 86400 # Allow backups to take up to 24 hours per database
$databases = $server.Databases
$script:totalsteps = $databases.count
############ NEW NEW NEW NEW ###########
if($script:totalsteps -eq $null -or $script:totalsteps -eq 0)
{
    $script:totalsteps = $databases.count * 4
    send-mailmessage -from "me@example.com" -to "me@example.com" -subject "Server Null: $server" -smtpserver "mail.example.com" -body "FIRST ATTEMPT"
}
########################################
if($script:totalsteps -eq $null -or $script:totalsteps -eq 0)
{
    $body = "Backup start:" +  $now.tostring("yyyy-MM-dd hh:mm:ss tt") + "`r`n" + 
        "Error: " + (get-date).tostring("yyyy-MM-dd hh:mm:ss tt") + "`r`n" + 
        "`$script:totalsteps: " + $script:totalsteps + "`r`n" + 
        "`$databases.count: " + $databases.count + "`r`n" + 
        "`$databases: " + $databases + "`r`n" + 
        "`$server: " + $server
    send-mailmessage -from "me@example.com" -to "me@example.com" -subject "Server Null: $server" -smtpserver "mail.example.com" -body $body
}
4

1 に答える 1

2

ここで推測するだけですが、割り当ては$databases変数への最初のアクセスであるため、これらの評価は遅延していると思います。そのため、最初に接続を開く必要があるため、データベースを列挙しようとするとタイムアウトが発生する可能性があります。その後、すでにデータを取得しているため、2 回目に使用するときに使用できます。ただし、確認するのは少し難しいです。

メールと一緒に変数も送信することをお勧め$Errorします。実際には理由が含まれている可能性があります

于 2013-05-02T07:14:45.993 に答える