我成功使用Powershell和SMO来备份大多数数据库。但是,我有几个大型数据库中收到“超时”错误“System.Data.SqlClient.SqlException:超时过期”。时光在10分钟时一直发生。我已经尝试将ConnectionContext.StatementTimeout设置为0,6000,并且设置为[System.Int32] :: MaxValue。设置没有区别。我发现许多Google参考文献指出将其设置为0使其无限。无论我尝试什么,超时都会持续10分钟。我甚至将服务器上的远程查询超时设置为0(通过Studio Manager)无济于事。以下是我设置超时和实际备份功能的SMO连接。下面是我的脚本的输出。忽略SMO ConnectionContext.StatementTimeout设置
UPDATE 有趣的是,我用C#编写了使用VS 2008的备份功能,超时重写在该环境下工作。我正在将该C#过程合并到我的Powershell脚本中,直到我可以找出为什么超时覆盖不适用于Powershell。 这非常烦人!
function New-SMOconnection {
Param ($server,
$ApplicationName= "PowerShell SMO",
[int]$StatementTimeout = 0
)
# Write-Debug "Function: New-SMOconnection $server $connectionname $commandtimeout"
if (test-path variable:\conn) {
$conn.connectioncontext.disconnect()
} else {
$conn = New-Object('Microsoft.SqlServer.Management.Smo.Server') $server
}
$conn.connectioncontext.applicationName = $applicationName
$conn.ConnectionContext.StatementTimeout = $StatementTimeout
$conn.connectioncontext.Connect()
$conn
}
$smo = New-SMOConnection -server $server
if ($smo.connectioncontext.isopen -eq $false) {
Throw "Could not connect to server $($server)."
}
Function Backup-Database {
Param([string]$dbname)
$db = $smo.Databases.get_Item($dbname)
if (!$db) {"Database $dbname was not found"; Return}
$sqldir = $smo.Settings.BackupDirectory + "\$($smo.name -replace ("\\", "$"))"
$s = ($server.Split('\'))[0]
$basedir = "\\$s\" + $($sqldir -replace (":", "$"))
$dt = get-date -format yyyyMMdd-HHmmss
$dbbk = new-object ('Microsoft.SqlServer.Management.Smo.Backup')
$dbbk.Action = 'Database'
$dbbk.BackupSetDescription = "Full backup of " + $dbname
$dbbk.BackupSetName = $dbname + " Backup"
$dbbk.Database = $dbname
$dbbk.MediaDescription = "Disk"
$target = "$basedir\$dbname\FULL"
if (-not(Test-Path $target)) { New-Item $target -ItemType directory | Out-Null}
$device = "$sqldir\$dbname\FULL\" + $($server -replace("\\", "$")) + "_" + $dbname + "_FULL_" + $dt + ".bak"
$dbbk.Devices.AddDevice($device, 'File')
$dbbk.Initialize = $True
$dbbk.Incremental = $false
$dbbk.LogTruncation = [Microsoft.SqlServer.Management.Smo.BackupTruncateLogType]::Truncate
If (!$copyonly) {
If ($kill) {$smo.KillAllProcesses($dbname)}
$dbbk.SqlBackupAsync($server)
}
$dbbk
}
Started SQL backups for server LCFSQLxxx\SQLxxx at 05/06/2010 15:33:16
Statement TimeOut value set to 0.
DatabaseName : OperationsManagerDW
StartBackupTime : 5/6/2010 3:33:16 PM
EndBackupTime : 5/6/2010 3:43:17 PM
StartCopyTime : 1/1/0001 12:00:00 AM
EndCopyTime : 1/1/0001 12:00:00 AM
CopiedFiles :
Status : Failed
ErrorMessage : System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
The backup or restore was aborted.
10 percent processed.
20 percent processed.
30 percent processed.
40 percent processed.
50 percent processed.
60 percent processed.
70 percent processed.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
Ended backups at 05/06/2010 15:43:23
我正在使用SqlBackup而不是SqlBakcupAsync,但此技巧仍适用于我。我正在传递服务器名称,以便创建新的连接。在切换到将ConnectionContext.StatementTimeout设置为[Int32] :: MaxValue的服务器对象后,我可以在没有命令超时的情况下执行备份。 – 2012-12-20 21:17:59