2
我有一個奇怪的問題,大概只有100次出現。我有一個使用SQL的SMO庫進行數據庫備份的PowerShell腳本。下面是我用來解決該問題的相關代碼剪斷: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 "[email protected]" -to "[email protected]" -subject "Server Null: $server" -smtpserver "mail.example.com" -body $body
}
的問題是,曾經在一段時間的if語句評價真實,我得到的是看起來的電子郵件,如:
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默默地失敗了變量賦值,並且繼續前進。
99的100次if語句是錯誤的,我沒有收到電子郵件。我不明白爲什麼$script:totalsteps
作業沒有100%的時間工作。有任何想法嗎?還有什麼可以嘗試解決此問題?
UPDATE
爲了測試懶惰評價理論,我已經改變了代碼爲:
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 "[email protected]" -to "[email protected]" -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 "[email protected]" -to "[email protected]" -subject "Server Null: $server" -smtpserver "mail.example.com" -body $body
}
只是猜測這裏,但因爲任務是在'$ databases'變量的第一次訪問。我相信這些評估是懶惰的,所以當它試圖枚舉數據庫時可能會超時,因爲它首先需要打開一個連接。之後,您已經提取了數據,因此當您第二次使用該數據時可用。雖然有點難以驗證。 – carlpett 2013-04-30 13:45:46
我會建議沿着'$ Error'變量發送郵件,它可能實際上包含原因 – carlpett 2013-04-30 13:46:28
好的想法。一位同事建議在分配和if語句之間增加一個睡眠,所以我已經做到了。我還在電子郵件中添加了$ error變量。我敢打賭你第一次懶惰的評估是正確的。我可能會嘗試在if語句中重新分配變量以查看是否修復了它。但是,在我看到我剛剛做出的改變證明是否有用之後,我會嘗試一下。我將在第二天或第二天更新。 – 2013-04-30 14:51:58