Powershell恢复脚本超时

时间:2017-06-14 13:14:25

标签: sql-server powershell sql-server-2008-r2

我有一个Powershell脚本based on this example,我一直用它来自动化我的数据库恢复,现在已经没有问题了。

最近它开始失败并抛出超时错误。

要突出显示该示例中的代码块:

############################################################################
# Restore db Script block
############################################################################
[ScriptBlock] $global:RestoreDBSMO = {
    param([string] $newDBName, [string] $backupFilePath, [bool] $isNetworkPath = $true, [string] $newDataPath, [string] $newLogPath)
# http://www.codeproject.com/Articles/110908/SQL-DB-Restore-using-PowerShell
    try
    {
        # Load assemblies
        [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
        [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
        [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
        [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

        # Create sql server object
        $server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "(local)"

        # Copy database locally if backup file is on a network share
        if($isNetworkPath)
        {
            $fileName = [IO.Path]::GetFileName($backupFilePath)
            $localPath = Join-Path -Path $server.DefaultFile -ChildPath $fileName
            Copy-Item $backupFilePath $localPath
            $backupFilePath = $localPath
        }

        # Create restore object and specify its settings
        $smoRestore = new-object("Microsoft.SqlServer.Management.Smo.Restore")
        $smoRestore.Database = $newDBName
        $smoRestore.NoRecovery = $false;
        $smoRestore.ReplaceDatabase = $true;
        $smoRestore.Action = "Database"

        # Create location to restore from
        $backupDevice = New-Object("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFilePath, "File") 
        $smoRestore.Devices.Add($backupDevice)

        # Give empty string a nice name
        $empty = ""

        # Specify new data file (mdf)

           $smoRestoreDataFile = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
            if (($newDataPath -eq $null) -or ($newDataPath -eq $empty)) { #use exixting path
           $defaultData = $server.DefaultFile
            if (($defaultData -eq $null) -or ($defaultData -eq $empty))
            {
                $defaultData = $server.MasterDBPath
            }
        } Else {$defaultData = $newDataPath}
        $fullPath = Join-Path -Path $defaultData -ChildPath ($newDBName + "_Data.mdf")
        $smoRestoreDataFile.PhysicalFileName = $fullPath

        # Specify new log file (ldf)
        $smoRestoreLogFile = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
        if (($newLogPath -eq $null) -or ($newLogPath -eq $empty)) { #use exixting path
            $defaultLog = $server.DefaultLog
            if (($defaultLog -eq $null) -or ($defaultLog -eq $empty))
            {
                $defaultLog = $server.MasterDBLogPath
            } 
        } Else {$defaultLog = $newLogPath}
        $fullPath = Join-Path -Path $defaultLog -ChildPath ($newDBName + "_Log.ldf")
        $smoRestoreLogFile.PhysicalFileName = $fullPath

        # Get the file list from backup file
        $dbFileList = $smoRestore.ReadFileList($server)

        # The logical file names should be the logical filename stored in the backup media
        $smoRestoreDataFile.LogicalFileName = $dbFileList.Select("Type = 'D'")[0].LogicalName
        $smoRestoreLogFile.LogicalFileName = $dbFileList.Select("Type = 'L'")[0].LogicalName

        # Add the new data and log files to relocate to
        $smoRestore.RelocateFiles.Add($smoRestoreDataFile)
        $smoRestore.RelocateFiles.Add($smoRestoreLogFile)

        # Restore the database
        $smoRestore.SqlRestore($server)

        "Database restore completed successfully"
    }
    catch [Exception]
    {
        "Database restore failed:`n`n " + $_.Exception
    }
    finally
    {
        # Clean up copied backup file after restore completes successfully
        if($isNetworkPath)
        {
            Remove-Item $backupFilePath
        }
    }
}

执行实际还原时,会抛出以下错误:

Restoring DB...
0
1
Database restore failed:

 Microsoft.SqlServer.Management.Smo.FailedOperationException: Restore failed for Server 'SRV_MIC_DEV'.  ---> Microsoft.SqlServer.Management.Common.ExecutionFailureException: An exception occurred while executing a Transact-SQL statement or batch. ---> 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.
   at Microsoft.SqlServer.Management.Common.ConnectionManager.ExecuteTSql(ExecuteTSqlAction action, Object execObject, DataSet fillDataSet, Boolean catchException)
   at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
   --- End of inner exception stack trace ---
   at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
   at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(StringCollection sqlCommands, ExecutionTypes executionType)
   at Microsoft.SqlServer.Management.Smo.ExecutionManager.ExecuteNonQuery(StringCollection queries)
   at Microsoft.SqlServer.Management.Smo.BackupRestoreBase.ExecuteSql(Server server, StringCollection queries)
   at Microsoft.SqlServer.Management.Smo.Restore.SqlRestore(Server srv)
   --- End of inner exception stack trace ---
   at Microsoft.SqlServer.Management.Smo.Restore.SqlRestore(Server srv)
   at SqlRestore(Object , Object[] )
   at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformation methodInformation, Object[] originalArguments)

我已经尝试查看Powershell文档和其他链接,并注意到有些网站提到Powershell cmdlet有600秒的默认超时。

我正在尝试从Powershell或SQL Server中找到增加此超时的解决方案,但我对文档或常规网络搜索没有任何好运。

我的脚本是否有任何快速修复可以增加超时或简单的替代方法?

非常感谢任何帮助。

0 个答案:

没有答案