Восстановление базы данных не удается в SQL Server - PullRequest
3 голосов
/ 27 апреля 2011

Я написал сценарий PowerShell для резервного копирования моих баз данных с помощью консоли lite speed.

В процессе различные конфигурации считываются из связанного файла xml.

Теперь я хочувосстановить их, поэтому я снова использовал lite speed для его восстановления.

Но он возвращает мне ошибку

RESTORE DATABASE ненормально завершается.
Хвост журнала длябаза данных "AK4432_JIM1" не была заархивирована.Используйте BACKUP LOG WITH NORECOVERY для резервного копирования журнала, если он содержит работу, которую вы не хотите потерять.Используйте предложение WITH REPLACE или WITH STOPAT оператора RESTORE, чтобы просто перезаписать содержимое журнала.

Это говорит о том, что для журнала необходимо создать резервную копию.

Резервное копирование журнала приводит к возникновению этой ошибки (Почему я должен выполнять резервное копирование журнала ???)

"Неверный синтаксис рядом с 'C: \ Users \ak4432 \ Desktop \ PS \ Backup2 '.
Неправильный синтаксис рядом с ключевым словом' with '. Если этот оператор является распространенным табличным выражением, предложением xmlnamespaces или предложением контекста отслеживания изменений, предыдущий оператор должен заканчиваться точкой с запятой."
В C: \ Users \ ak4432 \ Desktop \ PS \ BackUpAndRollBackScript.ps1: 49 char: 29
+ $ cmd.ExecuteNonQuery <<<< () <br>+ CategoryInfo: NotSpecified: (:) [],
MethodInvocationException
+ FullyQualifiedErrorId: DotNetMethodException

Модель восстановления для БД - полная или BULK_LOGGED

Я прилагаю свой скрипт .ps для справки

function Get-ScriptDirectory
{
  $Invocation = (Get-Variable MyInvocation -Scope 1).Value
  Split-Path $Invocation.MyCommand.Path
}

function SendEmail($to, $subject, $body, $from, $attachLogFilePath,$attachErrorFilePath) 
{
  $to= "egalitarian@xyz.com"
  send-mailmessage -from $from  -to $to -subject $subject -body $body  -smtpServer "zsserver3.zs.local" -Attachments $attachLogFilePath,$attachErrorFilePath
}

function PutDbOffline($connectionString,$databaseName,$logFilePath,$dbBackUpFolder,$serverName,$processName, $processPath, $processArguments, $onError, $backup)
{
  # connect to Db and then get the DB offline 
  $connection = new-object System.Data.SqlClient.SqlConnection($connectionString)
  $connection.open()
  $sqlQuery = "USE MASTER; EXEC sp_dboption N`'" + $databaseName + "`' , N`'offline`', N`'true`'"
  $cmd = new-object "System.Data.SqlClient.SqlCommand" ($sqlQuery, $connection)
  $cmd.ExecuteNonQuery()
  $connection.close()
}

function Restore($connectionString,$databaseName,$logFilePath,$dbBackUpFolder,$serverName,$processName, $processPath, $processArguments, $onError, $backup)
{
   $combinedProcessPath= Join-Path $processPath $processName

   #dump the output to a log file
   $logFileName =  $processName + $databaseName
   $logFileName+= "_"
   $logFileName += "{0:MMddyyyy-HH mm}" -f (Get-Date) 
   $combinedLogFilePath = Join-Path ($logFilePath) ($logFileName)
   $combinedErrorLogFilePath = $combinedLogFilePath + "_error"
   $dbBackUpFile = $databaseName + ".BAK"
   $databaseBackUpPath = Join-Path ($dbBackUpFolder) ($dbBackUpFile)

   $processArguments =  "" 

   if($backup -eq "Yes")
   {
        $connection = new-object System.Data.SqlClient.SqlConnection($connectionString)
        $connection.open()

        $sqlQuery = "BACKUP LOG " + $databaseName + " TO N `'" + $dbBackUpFolder + "`'  WITH NORECOVERY ;" 
        $cmd = new-object "System.Data.SqlClient.SqlCommand" ($sqlQuery, $connection)
        $cmd.ExecuteNonQuery()
        $connection.close()
        $processArguments = " -S " + $serverName + " -T -B Database -D " + $databaseName + " -F `""+ $databaseBackUpPath + "`"" 
   }
   else
   {
      #  PutDbOffline $connectionString $databaseName $logFilePath $dbBackUpFolder $serverName $processName, $processPath $processArguments $onError  $backup

        $processArguments = " -S " + $serverName +  " -R  DataBase -D " + $databaseName + " -F `"" + $databaseBackUpPath + "`"" 
   }

   $process = Start-Process -PassThru -Filepath $combinedProcessPath -WorkingDirectory $processPath -ArgumentList $processArguments -RedirectStandardOutput $combinedLogFilePath -RedirectStandardError $combinedErrorLogFilePath -wait -NoNewWindow

   if ($process.ExitCode -ne 0)
   {
       $mailSubject = "[02SS Back Up Status] " + $processName + " failed on "  + $serverName
       $body = "Process Failed, Exited with Code - " + $process.ExitCode + ". See attached files for details."  

       if($onError -eq "Break")
       {
          $body = $body + " Breaking from the power shell script."
          SendEmail "" $mailSubject $body "O2SSConversion@zsassociates.com" $combinedLogFilePath  $combinedErrorLogFilePath 
          return  "FAILED"
       }
       else
       {                
          SendEmail "" $mailSubject $body "O2SSConversion@zsassociates.com" $combinedLogFilePath  $combinedErrorLogFilePath 
       }
    }
    else
    {
       $mailSubject = "[02SS Back Up Status] " + $processName + " ran successfully on "  + $serverName
       $body = "Process Successful, Exited with Code - " + $process.ExitCode + ". See attached files for details."  
       SendEmail "" $mailSubject $body "O2SSConversion@zsassociates.com" $combinedLogFilePath  $combinedErrorLogFilePath 
    }
}


# Load the XML FILE 
$sourceFile = Join-Path (Get-ScriptDirectory) ("BackUpAndRollBackConfiguration.xml")
$xDoc = new-Object System.Xml.XmlDocument
$xDoc.Load($sourceFile)

# Get settings to connect to DB  
$serverName = $xDoc.selectSingleNode("/configuration/appSettings/ServerName").get_InnerXml()
$databaseName = $xDoc.selectSingleNode("/configuration/appSettings/Database").get_InnerXml()
$userName = $xDoc.selectSingleNode("/configuration/appSettings/UserName").get_InnerXml()
$password = $xDoc.selectSingleNode("/configuration/appSettings/Password").get_InnerXml()
$logFilePath = $xDoc.selectSingleNode("/configuration/appSettings/logFilePath").get_InnerXml()
$dbBackUpFolder = $xDoc.selectSingleNode("/configuration/appSettings/DatabaseBackUpFolder").get_InnerXml()
#Create connection string
$connectionString = "server=" + $serverName + ";Database=" + $databaseName +";uid=" + $userName + ";pwd=" + $password

#Get Settings to decide whether its a RollBack or BackUp
$backup = $xDoc.selectSingleNode("/configuration/appSettings/BackUp").get_InnerXml()

#Declare an array to hold DB names .. Being populated later
$dbIdentifiers =@()

# Get the Process Parameter from File

$processName=""
$processPath=""
$processArguments=""
$onError = ""

$processes = $xDoc.selectnodes("/configuration/processes/process")
foreach ($process in $processes) {

    $processName=$process.selectSingleNode("processName").get_InnerXml()
    $processPath=$process.selectSingleNode("processPath").get_InnerXml()
    $processArguments=$process.selectSingleNode("processArguments").get_InnerXml()
    $onError = $process.selectSingleNode("OnError").get_InnerXml()    

}


if($backup -eq "No")
{
$returnType = Restore $connectionString $databaseName $logFilePath $dbBackUpFolder $serverName $processName $processPath $processArguments $onError $backup
if ($returnType -eq "FAILED")
{
break
}
}

#Migrate the Master Db And Scn Dbs Now

# Connect to Db and then get the SCN Db Identifier

            $Table = new-object System.Data.DataTable
            $sqlConn = new-object System.Data.SqlClient.SqlConnection($connectionString)
            $sqlConn.open()
            $adapter = new-object System.Data.SqlClient.SqlDataAdapter("SELECT DBIDENTIFIER FROM SCENARIOS",$sqlConn)
            $adapter.Fill($Table)
            $sqlConn.close()
            # Populate the db Identifer Array to include  master Db and SCN Db.
            if($backup -eq "Yes")
            {
              $dbIdentifiers += , $databaseName
            }
            foreach ($row in $Table) 
            {
             $dbIdentifiers+= , $row.DBIDENTIFIER
            }


            foreach ($dbIdentifier in $dbIdentifiers) {
            if($processPath)
            {

            $returnType =  Restore $connectionString $dbIdentifier $logFilePath $dbBackUpFolder $serverName $processName $processPath $processArguments $onError $backup
            if ($returnType -eq "FAILED")
            {
                break
            }
            }
}

Может кто-нибудь помочь мне решить проблему, так как мой разум действительно перестал работать

Ответы [ 2 ]

1 голос
/ 29 августа 2011

В нем говорится, что журнал должен быть скопирован.(Почему я должен сделать резервную копию журнала ???)

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

Вот инструкции от Microsoft по резервному копированию хвоста журнала.

Этого также можно избежать, сначала сбросив базу данных, а затем восстановив ее, либо используя WITH REPLACE при восстановлении., который сообщает SQL Server, что вы перезаписываете эту базу данных чем-то совершенно другим.

0 голосов
/ 27 апреля 2011

Если вы выполняете резервное копирование в файл, правильный синтаксис будет следующим:

BACKUP LOG dbname TO DISK='path\to\filename' WITH NORECOVERY

Однако вам на самом деле не нужно создавать резервную копию журнала, если вам больше не нужны текущие данные (иэто то, что говорит сообщение об ошибке).Вам просто нужно предоставить WITH REPLACE опцию RESTORE, которая заменит существующие журнал и файлы данных.

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