2011-04-27 4 views
3
나는 라이트 속도 콘솔을 사용하여 내 데이터베이스를 백업하는 PowerShell 스크립트를 작성했습니다

에 실패합니다. 는 SQL 서버

이 과정에서 다양한 구성이 연결된 XML 파일에서 읽습니다.

은 지금은 복원하려는, 그래서 그것을 복원하기 위해 다시 라이트 속도를 사용했다.

그러나 그 날

RESTORE DATABASE 비정상적으로 종료되고 오류를 반환.
"AK4432_JIM1"데이터베이스의 로그 꼬리가 백업되지 않았습니다. NORECOVERY를 사용하여 BACKUP LOG WITH WITH 에 손실을 원하지 않는 작업이있는 경우 로그를 백업하십시오. 은 함께 교체 사용하거나 에 RESTORE 문 STOPAT 절을 바로 로그의 내용을 덮어 씁니다.

그것은 로그를 백업해야합니다 말한다. '바탕 화면 \ PS \ Backup2 \ \ 사용자 \ ak4432 C'로그를 백업

이 오류 (왜해야 내가 다시 로그 ???까지) 근처

"잘못된 구문을 던졌습니다. 이 사항이 공통 테이블 식, XMLNAMESPACES 절 또는 상황에 맞는 절을 추적 변경이 '와'키워드 근처
잘못된 구문. 이전 문은 세미콜론으로 종료해야합니다. " C에서
CHAR : 29
+ $ cmd.ExecuteNonQuery < < < <()
+ CategoryInfo : NotSpecified (:) []
화상 \ PS \ BackUpAndRollBackScript.ps1 \ 사용자 \ ak4432을 \ MethodInvocationException는 는 FullyQualifiedErrorId +
: DotNetMethodException는 DB에 대한 복구 모델은 전체 또는 BULK_LOGGED

012 중

입니다 난 당신이

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

function SendEmail($to, $subject, $body, $from, $attachLogFilePath,$attachErrorFilePath) 
{ 
    $to= "[email protected]" 
    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 "[email protected]" $combinedLogFilePath $combinedErrorLogFilePath 
      return "FAILED" 
     } 
     else 
     {     
      SendEmail "" $mailSubject $body "[email protected]" $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 "[email protected]" $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 [email protected]() 

# 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 
      } 
      } 
} 

누군가가 내 마음이 정말 파일로 백업하는 경우

답변

0

지금 작동이 중지되었습니다 나를이 문제를 해결하는 데 도움이 수, 올바른 구문을 참조 내 .PS 스크립트를 부착하고 될 것이다 : 당신은 더 이상 현재 데이터가 필요하지 않은 경우

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

그러나, 실제로 백업 로그를 필요가 없습니다 (그 오류 메시지의 말씀입니다). 기존 로그 및 데이터 파일을 대체 할 RESTOREWITH REPLACE 옵션을 제공하면됩니다.

1

그것은 로그를 백업해야합니다 말한다. (왜 로그를 백업해야합니까?)

이것은 안전 기능입니다. SQL Server는 실제 데이터베이스를 동일한 데이터베이스의 과거 백업으로 덮어 쓰고 있다고 생각하므로 마지막 트랜잭션 로그 백업 이후 발생한 트랜잭션을 잡기 위해 먼저 로그의 끝 부분을 백업해야합니다.

여기 instructions from Microsoft on backing up the tail of the log.

당신은 또한, 또는 당신은 완전히 다른 무언가 해당 데이터베이스를 덮어하고 SQL 서버를 알려줍니다, 복원 WITH가에 교체 사용하여 먼저 데이터베이스를 삭제하고 복원하여이를 방지 할 수 있습니다.