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 次 if 语句中有 99 次是错误的,我没有收到电子邮件。我不明白为什么$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变量的第一次访问:我相信对这些的评估是惰性的,所以当它尝试枚举数据库时可能会超时,因为它首先需要打开一个连接。之后,您已经获取了数据,因此在您第二次使用时可以使用它。不过,有点难以验证。

我建议也将$Error变量与您的电子邮件一起发送,它实际上可能包含原因

于 2013-05-02T07:14:45.993 回答