Перед восстановлением резервной копии в SQL Server важно проверить файл резервной копии, чтобы убедиться в его целостности. Это можно сделать с помощью различных команд SQL Server, таких как RESTORE HEADERONLY, RESTORE FILELISTONLY и RESTORE VERIFYONLY. Однако, если есть несколько файлов резервной копии, может потребоваться много времени, чтобы проверить каждый из них отдельно.
В этой статье мы рассмотрим сценарий PowerShell, который может помочь вам проверить несколько файлов резервной копии и экспортировать результаты в файл для последующего использования.
Сценарий PowerShell
Вот сценарий PowerShell, который можно использовать для проверки файлов резервной копии SQL Server:
$global:backupsets = New-Object System.Collections.Hashtable
$global:restoreHeaderOnly = New-Object System.Collections.Hashtable
$global:restoreFilelistOnly = New-Object System.Collections.Hashtable
$global:restoreScripts= New-Object System.Collections.Hashtable
function global:run-sql ([String]$sql, [String]$server, [String]$database="master") {
$connectionString = "Server="+$server+";Database="+$database+";Trusted_Connection=yes"
$conn = new-object System.Data.SqlClient.SqlConnection $connectionString
$conn.Open()
$comm = $conn.CreateCommand()
$comm.CommandText = $sql
$reader = $comm.ExecuteReader()
while($reader.Read()) {
$row = new-object PSObject
for($i = 0; $i -lt $reader.FieldCount; ++$i) {
add-member -inputObject $row -memberType NoteProperty -name $reader.GetName($i) -value $reader.GetValue($i)
}
write-output $row
}
$reader.Close()
$conn.Close()
}
function global:verifyBackup([String]$backupPath, [String]$tempPath=$backupPath, [String]$sqlserver="localhost") {
$global:backupsets = New-Object System.Collections.Hashtable
$global:restoreHeaderOnly = New-Object System.Collections.Hashtable
$global:restoreFilelistOnly = New-Object System.Collections.Hashtable
$global:restoreVerifyOnly = New-Object System.Collections.Hashtable
$files=gci -Path $backupPath | where{$_.Extension -match "bak|trn"} | select name | sort-object name
foreach($file in $files) {
$filepath=$backupPath+"\" + $file.Name
$sqlcmd="restore headeronly from disk='" + $filepath+"'"
$headinfos=global:run-sql $sqlcmd $sqlserver
foreach ($headinfo in $headinfos) {
if ($headinfo){
$key=$headinfo.DatabaseName
if ($global:backupsets.ContainsKey($key)) {
$global:backupsets.Item($key).add($filepath)
} else {
$temp=New-Object System.Collections.ArrayList
$temp.add($filepath)
$global:backupsets.Add($key, $temp)
}
}
}
}
# run restore headeronly
foreach ($fileKey in $global:backupsets.keys) {
$sqlcmd="restore headeronly from "
$backupfiles=$global:backupsets.Item($fileKey)
foreach ($backupfile in $backupfiles) {
$sqlcmd=$sqlcmd+"disk='"+$backupfile+"',"
}
if ($sqlcmd.EndsWith(",")) {
$sqlcmd=$sqlcmd.TrimEnd(",")
}
$restoreInfo=global:run-sql $sqlcmd $sqlserver
$global:restoreHeaderOnly.Add($fileKey, $restoreInfo)
$csvfile=$backupPath+"\"+$fileKey+"_headeronly.csv"
$restoreInfo | Export-Csv -Path $csvfile
}
# run restore filelistonly
foreach ($fileKey in $global:backupsets.keys) {
$sqlcmd="RESTORE FILELISTONLY from "
$backupfiles=$global:backupsets.Item($fileKey)
foreach ($backupfile in $backupfiles) {
$sqlcmd=$sqlcmd+"disk='"+$backupfile+"',"
}
if ($sqlcmd.EndsWith(",")) {
$sqlcmd=$sqlcmd.TrimEnd(",")
}
$restoreInfo=global:run-sql $sqlcmd $sqlserver
$global:restoreFilelistOnly.Add($fileKey, $restoreInfo)
$csvfile=$backupPath+"\"+$fileKey+"_filelistonly.csv"
$restoreInfo | Export-Csv -Path $csvfile
}
# run restore verifyonly
foreach ($fileKey in $global:backupsets.keys) {
$sqlcmd="RESTORE VERIFYONLY from "
$backupfiles=$global:backupsets.Item($fileKey)
foreach ($backupfile in $backupfiles) {
$sqlcmd=$sqlcmd+"disk='"+$backupfile+"',"
}
if ($sqlcmd.EndsWith(",")) {
$sqlcmd=$sqlcmd.TrimEnd(",")
}
$sqlcmd=$sqlcmd + " with "
$fileList=$global:restoreFilelistOnly.Item($fileKey)
foreach ($file in $fileList) {
$logcalName=$file.LogicalName
$physicalName=$file.PhysicalName | split-path -leaf
$sqlcmd=$sqlcmd+ " move '"+$logcalName + "' to '" + $tempPath+"\"+ $physicalName+"',"
}
if ($sqlcmd.EndsWith(",")) {
$sqlcmd=$sqlcmd.TrimEnd(",")
}
$csvfile=$backupPath+"\"+$fileKey+"_verifyonly.txt"
$cmd="sqlcmd -E -S " + $sqlserver + " -Q `" " + $sqlcmd + " `" -o `""+ $csvfile+"`""
invoke-expression $cmd
$msg="Verify backup of database [" +$fileKey+ "] is done: `n"
$msg+= gc $csvfile
Write-Output $msg
Add-Content $csvfile "`n"
Add-Content $csvfile "$sqlcmd"
}
}Как использовать сценарий
Следуйте этим шагам, чтобы использовать сценарий PowerShell:
- Сохраните сценарий в файл с расширением .ps1.
- Откройте PowerShell и перейдите в каталог, где сохранен сценарий.
- Запустите сценарий, введя его имя и нажав Enter.
- После запуска сценария вы можете проверить файлы резервной копии, используя функцию
verifyBackup, за которой следует путь к папке. Например:verifyBackup "C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Backup\AWD". - Сценарий выведет результаты проверки резервной копии и также экспортирует подробные отчеты для каждого набора резервных копий в той же папке.
Обратите внимание, что текущая версия сценария работает только с одним набором резервных копий на устройство. Кроме того, для функции verifyBackup есть три параметра:
$backupPath: путь к файлу резервной копии.$tempPath: путь к временному файлу для “restore verifyonly”. По умолчанию он совпадает с$backupPath.$sqlserver: имя экземпляра SQL Server. По умолчанию используется “localhost”.
Используя этот сценарий PowerShell, вы можете легко проверить несколько файлов резервной копии SQL Server и убедиться в их целостности перед их восстановлением.