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