我有一个脚本,我根据我找到的脚本Start-Migration创建了一个PowerShell脚本。这是一个很棒的剧本,给了我很多很好的想法;但是,在尝试恢复超过10分钟的大型数据库或数据库时,我遇到了一些问题。我试图使用它们发现的invoke-sqlcmd2函数和microsoft.sqlserver.management.smo命名空间的恢复类。这两个都在10分钟后超时。我还尝试增加连接超时,甚至将连接设置为1200.任何建议都会受到欢迎。
Function Restore-SQLDatabase {
<#
.SYNOPSIS
Restores .bak file to SQL database. Creates db if it doesn't exist. $filestructure is
a custom object that contains logical and physical file locations.
.EXAMPLE
$filestructure = Get-SQLFileStructures $sourceserver $destserver $ReuseFolderstructure
Restore-SQLDatabase $destserver $dbname $backupfile $filestructure
.OUTPUTS
$true if success
$true if failure
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[object]$server,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$dbname,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]$backupfile,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[object]$filestructure
)
$servername = $server.Name
$server.ConnectionContext.StatementTimeout = 0
$restore = New-Object "Microsoft.SqlServer.Management.Smo.Restore"
foreach ($file in $filestructure.databases[$dbname].destination.values) {
$movefile = New-Object "Microsoft.SqlServer.Management.Smo.RelocateFile"
$movefile.LogicalFileName = $file.logical
$movefile.PhysicalFileName = $file.physical
$null = $restore.RelocateFiles.Add($movefile)
}
Write-Host "Restoring $dbname to $servername" -ForegroundColor Yellow
try{
$Percent = [Microsoft.SqlServer.Management.Smo.PercentCompleteEventHandler]{
Write-Progress -Id 1 -Activity "Restoring $dbname to $ServerName" -PercentComplete $_.Percent -Status ([System.String]::Format("Progress: {0}%",$_.Percent))
}
$restore.add_PercentComplete($Percent)
$restore.PercentCompleteNotification = 1
$restore.add_Complete($Complete)
$restore.ReplaceDatabase = $true
$restore.Database = $dbname
$restore.Action = "Database"
$restore.NoRecovery = $false
$device = New-Object -TypeName Microsoft.SqlServer.Management.Smo.BackupDeviceItem
$device.Name = $backupfile
$device.DeviceType = "File"
$restore.Devices.Add($device)
Write-Progress -Id 1 -Activity "Restoring $dbname to $servername" -PercentComplete 0 -Status([System.String]::Format("Progress: {0}%",0))
$restore.SqlRestore($servername)
# $query = $restore.Script($ServerName)
# Write-Host $query
# Invoke-Sqlcmd2 -ServerInstance $servername -Database master -Query $query -ConnectionTimeout 1200
# Write-Host "Restoring $dbname to $servername from " $restore.Devices.ToString() -ForegroundColor Magenta
Write-Progress -Id 1 -Activity "Restore $dbname to $servername" -Status "Complete" -Completed
return $true
}
catch{
Write-Error $_.Exception.ToString()
Write-Warning "Restore failed: $($_.Exception.InnerException.Message)"
return $false
}
当还原过程发生时,$ restore.SqlRestore($ ServerName),在我的大型数据库上,它返回说该脚本超时。我想弄清楚如何纠正这个问题。我已经尝试增加statementtimeout = 1200并且它在10分钟后仍然停止。我甚至试图给我们一个invoke-sqlcmd你可以看到我在尝试不同的选项时评论它。我现在正处于斗智斗勇的境地。
答案 0 :(得分:0)
如果您必须使用找到的脚本
我认为这行`$ server.ConnectionContext.StatementTimeout = 0'实际上并没有做任何事情或更改超时阈值。
尝试将行更改为此行,而不是
$server = New-Object("Microsoft.SqlServer.Management.Smo.Server") $server
$server.ConnectionContext.StatementTimeout = 0
$server.ConnectionContext.Connect()
但是,我建议完全避免使用这种方法,因为您可以使用更简单的SQLPS Cmdlet。您使用的方法来自很久以前,我们没有实际的PowerShell cmdlet来使用SQL。
现在,我们有了Restore-SQLDatabase cmdlet,它允许你在一行中完成你的代码现在在~30行中所做的!!
如何使用Restore-SQLDatabase
这更容易,我想你真的会感谢我。
Restore-SqlDatabase -ServerInstance "$server\InstanceName" `
-Database $dbname `-BackupFile $BackupFile
并且......就是这样。一条线!而且你也可以在这里轻松指定超时,这与之前不同。要指定最大超时:
Restore-SqlDatabase -ServerInstance "$server\InstanceName" `
-Database $dbname -BackupFile $BackupFile -ConnectionTimeout 0
这应该让你开始。相信我,使用Cmdlet比使用在线查找的随机脚本要容易得多。
答案 1 :(得分:0)
好的,我让它上班了。我不完全确定它为什么有效,但这就是我所做的。我创建了一个参数$ Server,如下所示:
$Server = New-Object Microsoft.SqlServer.Management.Smo.Server $Source
$Server.ConnectionContext.ConnectTimeout = 0
现在当我调用实际执行恢复的功能时,我正在做一些我不需要做的事情:
$ServerName = $server.Name
而不是使用$ ServerName,我使用对象$ server:
$restore.SqlRestore($servername) # Original Script
$restore.SqlRestore($server) # Change
现在它保持打开足够长的时间来完成恢复过程。