Ошибка восстановления резервной копии базы данных в новую базу данных с помощью smo и powershell - PullRequest
9 голосов
/ 26 февраля 2011

Принимая резервную копию базы данных с другого сервера, я пытаюсь восстановить в sqlexpress на localhost. Это восстановление будет работать через графический интерфейс, но у меня возникли проблемы с восстановлением с помощью powershell. Я получаю следующее сообщение об ошибке:

Exception calling "SqlRestore" with "1" argument(s): "Restore failed for Server
+ $smoRestore.SqlRestore <<<< ($server)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

Сообщение об ошибке указывает на символ 23 этой строки:

        $smoRestore.SqlRestore($server)

Сценарий:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null

Import-Module PSCX
Import-Module WebAdministration

function GetLatestItem(){
    param([string]$RemotePath)
    $returnString = Get-ChildItem $RemotePath -force -filter "*.7z" | sort @{expression={$_.LastWriteTime}; Descending=$true} | select Name -first 1
    return $returnString.Name
}

function DatabaseExists(){
    param([Microsoft.SqlServer.Management.Smo.Server]$server,[string]$databaseName)
    foreach($database in $server.Databases){
        if($database.Name -eq $databaseName){
            $true
        }
    }
    $false
}

$LocalFile = "C:\backups\backupname.bak.7z"
$LocalFilePath = "C:\backups\"   

Expand-Archive $Localfile $LocalFilePath    

# Most of the restore information was found at http://www.sqlmusings.com/2009/06/01/how-to-restore-sql-server-databases-using-smo-and-powershell/
$backupFile = $LocalFilePath + [IO.Path]::GetFileNameWithoutExtension($LocalFile)
[Microsoft.SqlServer.Management.Smo.Server]$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") ".\SQLEXPRESS"
$backupDevice = New-Object ("Microsoft.SqlServer.Management.Smo.BackupDeviceItem") ($backupFile, "File")
$smoRestore = New-Object Microsoft.SqlServer.Management.Smo.Restore

$smoRestore.NoRecovery = $true;
$smoREstore.ReplaceDatabase = $true;
$smoRestore.Action = "Database"
$smoRestore.PercentCompleteNotification = 10;
$smoRestore.Devices.Add($backupDevice)

# Get the details from the backup device for the database name and output that
$smoRestoreDetails = $smoRestore.ReadBackupHeader($server)
$databaseName = $smoRestoreDetails.Rows[0]["DatabaseName"]

"Database Name from Backup Header : " + $databaseName
$smoRestore.Database = $databaseName    

if(DatabaseExists $server $databaseName -not){
    $smoRestoreFile = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
    $smoRestoreLog = New-Object("Microsoft.SqlServer.Management.Smo.RelocateFile")
    $smoRestoreFile.LogicalFileName = $smoRestoreDetails.Rows[0]["DatabaseName"]
    $smoRestoreFile.PhysicalFileName = $server.Information.MasterDBPath + "\" + $smoRestore.Database + "_Data.mdf"
    $smoRestoreLog.LogicalFileName = $smoRestoreDetails.Rows[0]["DatabaseName"] + "_Log"
    $smoRestoreLog.PhysicalFileName = $server.Information.MasterDBPath + "\" + $smoRestore.Database + "_Log.ldf"
    $smoRestore.RelocateFiles.Add($smoRestoreFile)
    $smoRestore.RelocateFiles.Add($smoRestoreLog)
} 

$smoRestore.SqlRestore($server)
if($error.Count -eq 0){
}
else{
    $Error[0].exception.message
}

Ответы [ 2 ]

11 голосов
/ 26 февраля 2011

У меня есть сценарий, очень похожий на ваш, с некоторыми примечательными отличиями:

  • Перед вызовом SqlRestore я звоню $server.KillAllProcesses($databaseName).
  • У меня есть$smoRestore.NoRecovery = $false вместо $true
  • У меня есть $smoRestore.FileNumber = 1, которого у вас нет совсем.Я думаю, что это соответствует проверке файла из набора резервных копий в графическом интерфейсе.

У меня также есть аналогичный код для установки логических / физических имен файлов, но вместо использования $server.Information я извлекаю информациюиз реестра (не уверен, что "лучше").Еще одно отличие состоит в том, что я использую $smoRestore.ReadFileList вместо $smoRestore.ReadBackupHeader.

Вы также можете попробовать использовать несколько операторов Write-Host на ваших путях, чтобы убедиться, что они выглядят правильно, если вы еще этого не сделали.

Надеюсь, что один из перечисленных твиков решит вашу проблему.Дайте мне знать, если вам нужна дополнительная информация из моего сценария.

1 голос
/ 03 февраля 2015

У нас с коллегой возникла эта проблема, и после небольшого устранения неполадок мы обнаружили, что закрытие SQL Server Management Studio помогло.

Надеемся, что кто-то другой может пропустить все устраненные нами неполадки и это простое решениесэкономит им несколько часов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...