在SQL Server中,恢复数据库失败

3
我已经编写了一个PowerShell脚本,使用lite速度控制台备份我的数据库。在此过程中,各种配置从关联的xml文件中读取。现在我想还原它们,所以我再次使用lite速度来还原。但是它返回了一个错误。它说必须备份日志。备份日志会抛出以下错误(为什么我要备份日志?):“C:\Users\ak4432\Desktop\PS\Backup2”附近有语法错误。关键字“with”附近有语法错误。如果此语句是常见表达式、xmlnamespaces子句或更改跟踪上下文子句,则必须使用分号终止前面的语句。DB的恢复模型是完整或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
它说日志必须备份。(为什么要备份日志???)
这是一项安全功能。SQL Server认为您正在使用过去备份的同一数据库覆盖实时生产数据库,因此它希望您首先备份日志尾部以捕获自上次事务日志备份以来发生的任何事务。
这里是Microsoft关于备份日志尾部的说明
您还可以通过首先删除数据库然后恢复,或在恢复中使用WITH REPLACE来避免此问题,后者告诉SQL Server您正在使用完全不同的内容覆盖该数据库。

0

如果你要备份到文件,正确的语法应该是:

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

然而,如果您不再需要当前数据(这就是错误消息所说的内容),则实际上无需备份日志。您只需要在RESTORE中提供WITH REPLACE选项即可替换现有的日志和数据文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接