Мне не раз приходилось восстанавливать базы данных SQL Server из резервных файлов и при этом непременно либо резервная копия была получена с помощью не той системы, на которой предполагалось размещать восстановленную базу данных, либо эта копия поступала из неизвестного (но доверенного) источника. Так или иначе, перед тем, как приступать к восстановлению данных, я должен был получать сведения об именах файлов, о логических именах, местах размещения файлов, об их размерах и т.д. И уж во всяком случае, прежде чем браться за восстановление, мне приходилось получать информацию о том, какой объем пространства необходимо выделить для данной цели.
Получить сведения о деталях содержимого резервного файла средствами языка T-SQL довольно просто: для этого существует параметр FILELISTONLY команды RESTORE.
RESTORE FILELISTONLY FROM DISK = 'C:\MSSQL\MSSQL11.MSSQLSERVER\MSSQL\Backup\TicketSalesDB.bak' WITH FILE = 1 GO
В итоге искомые подробности отображаются в формате таблицы результатов (в среде SQL Server Management Studio), см. экран 1.
Экран 1. Таблица результатов в SQL Server Management Studio |
Этот метод работает, но если нужно использовать данную информацию для решения других задач, могут возникнуть дополнительные сложности. Технология PowerShell в сочетании с объектами SQL Server Management Objects (SMO) обеспечивает универсальный вариант получения интересующих нас данных. Как всегда, нужно подключиться к SQL Server с помощью объекта SMO Server, а затем создать объект Restore.
$srv = new-object ('Microsoft.SqlServer.Management.Smo.Server') WS12SQL $rs = new-object('Microsoft.SqlServer.Management.Smo.Restore')
Далее требуется определить элемент Backup Device Item, указывающий на резервный файл, и включить его в коллекцию Devices объекта Restore.
$bckfile = 'C:\MSSQL\MSSQL11.MSSQLSERVER\MSSQL\Backup\TicketSalesDB.bak' $bdi = new-object ('Microsoft.SqlServer.Management.Smo.BackupDeviceItem') ($bckfile, 'File') $rs.Devices.Add($bdi)
Теперь объект SMO располагает всей необходимой информацией, и для того, чтобы извлечь из резервного файла нужные детали, следует воспользоваться методом ReadFileList() объекта Restore. Чтобы увидеть методы и свойства, получить которые можно из файла результатов (они возвращаются в виде объекта ADO.NET DataTable), можно воспользоваться командой Get-Member, см. экран 2.
$fl = $rs.ReadFileList($srv)
Экран 2. Объект ADO.NET DataTable |
Далее вы можете извлечь интересующие вас свойства с помощью конвейера и преобразовать их в табличную форму, см. экран 3.
$fl | select LogicalName, Type, Size, PhysicalName | Format-Table –AutoSize
Экран 3. Таблица PowerShell |
Картина будет еще более наглядной, если произвести над содержимым некоторые действия с помощью хэш-таблиц. К примеру, мне удобнее работать с информацией, когда объемы данных выражены не в байтах, а в мегабайтах или в гигабайтах. Я заменяю свойство Size хэш-таблицей, которая выглядит следующим образом:
@{Name='SizeMB';Expression={$_.Size / 1MB}}
В результате размеры отдельных файлов отображаются в мегабайтах. Подобным же образом я предпочитаю разбивать свойство PhysicalName на компоненты Drive, Folder и File. Эта операция легко выполняется с помощью таких хэш-таблиц:
@{Name='Drive';Expression={Split-Path $_.PhysicalName -Qualifier}} @{Name='Folder';Expression={Split-Path $_.PhysicalName -Parent}} @{Name='File';Expression={Split-Path $_.PhysicalName -Leaf}}
После внесения описанных изменений упомянутая выше команда приобретает вид:
$fl | select LogicalName, Type, @{Name='SizeMB';Expression={$_.Size / 1MB}}, @{Name='Drive';Expression={Split-Path $_.PhysicalName -Qualifier}}, @{Name='Folder';Expression={Split-Path $_.PhysicalName -Parent}}, @{Name='File';Expression={Split- Path $_.PhysicalName -Leaf}} | Format-Table -AutoSize
Теперь читать результаты гораздо удобнее, см. экран 4.
Экран 4. Преобразованные результаты |
Добавив к пространству имен Win32_LogicalDisk вызов WMI, вы быстро найдете дисковые накопители на текущей системе, их размер (в Гбайт), а также объем свободного пространства (тоже в Гбайт) и убедитесь, что интересующую вас базу данных можно спокойно восстанавливать на данном сервере, см. экран 5.
$dsk = Get-WMIObject -Query 'select * from Win32_LogicalDisk where DriveType = 3' $dsk | select DeviceID, @{Name='SizeGB';Expression={$_.Size / 1GB}}, @{Name='FreeGB';Expression={$_.FreeSpace / 1GB }} | Format-Table -AutoSize
Экран 5. Информация о дисках системы для восстановления базы данных |
С помощью описанных инструментов вы можете осуществить быстрый анализ в порядке подготовки к восстановлению данных. Кроме того, на базе этих фрагментов кода можно создать сценарий, обеспечивающий автоматизацию всего процесса.