17.5.26
Клонирование с помощью аварийно-устойчивых снимков в Hyper-V
Если вы следили за моей серией статей о резервном копировании через снимки с помощью T-SQL (T-SQL Snapshot Backup), то большая часть из того, о чём я рассказывал, требовала участия SQL Server в создании снимка: заморозка операций записи, резервное копирование метаданных, скоординированный рабочий процесс. Эта статья покрывает другую сторону этого вопроса: клонирование, устойчивое к аварийному отказу (crash-consistent cloning). Никакой заморозки записи. Никакого резервного копирования. Никакого восстановления на момент времени. Просто клон тома «сырых» данных, который SQL Server автоматически восстанавливает при подключении.
Что такое аварийно-устойчивый снимок (Crash-Consistent Snapshot)?
Когда люди говорят о резервном копировании с помощью снимков для SQL Server, они часто сразу переходят к согласованным на уровне приложения снимкам (application-consistent snapshots) — тем, где SQL Server просят заморозить операции записи перед созданием снимка. Эта заморозка гарантирует, что каждая страница на диске отражает логически согласованное состояние базы данных.
Аварийно-устойчивый снимок — это другое. Мы делаем «фотографию» хранилища в определённый момент времени, не спрашивая разрешения у SQL Server. Никакой заморозки. Никакого «успокоения». Файлы базы данных на диске в момент создания снимка находятся в том же состоянии, в котором они были бы, если бы кто-то выдернул шнур питания.
Зачем вам это вообще может понадобиться? Потому что SQL Server уже научен, как восстанавливаться после потери питания. Именно для этого и нужно аварийное восстановление (crash recovery). Каждый раз, когда SQL Server запускается после нештатного завершения работы, он читает журнал транзакций, накатывает (rolls forward) все зафиксированные транзакции, которые не были записаны в файлы данных, и откатывает (rolls back) всё, что находилось в процессе выполнения в момент сбоя. Когда мы подключаем клон аварийно-устойчивого снимка, SQL Server автоматически выполняет тот же процесс. Вам просто нужно выполнить ATTACH или перевести базу данных в режим ONLINE, и он позаботится об остальном.
Важно: Аварийно-устойчивый снимок — это не стратегия резервного копирования для производственного восстановления. Восстановленная база данных будет транзакционно и физически согласована, но вы можете восстановиться только на момент создания снимка. Для производственного восстановления на момент времени (PITR) вам нужен согласованный на уровне приложения снимок с цепочкой журналов, о чём и говорится в других статьях серии T-SQL Snapshot Backup.
Где аварийно-устойчивый снимок действительно блистает, так это в обновлении баз данных для разработки/тестирования (dev/test) или отчётности: вы хотите получить самые свежие производственные данные, вам всё равно на потерю последних нескольких минут, и вы хотите сделать это максимально быстро с нулевым воздействием на исходный SQL Server. Я говорю своим заказчикам: если вы используете резервное копирование и восстановление для перемещения данных между системами, перестаньте это делать и начните делать это иначе.
Именно это и делает представленный ниже скрипт.
Схема хранилища (Storage Topology)
Прежде чем мы перейдём к коду, давайте разберёмся с окружением. В этой лабораторной среде у меня есть двухузловой кластер Hyper-V. SQL Server работает внутри виртуальной машины на каждом узле. Файлы базы данных TPCC-4T находятся на двух VHDX, которые хранятся на общем томе кластера (Cluster Shared Volume) hyperv-csv-01-DATA-PROD на базе Pure Storage FlashArray.
Стек хранилища:
Том FlashArray (hyperv-csv-01-DATA-PROD)
└── Общий том кластера (CSV) -> C:\ClusterStorage\Volume10 на узле HV Node 1
└── VHDX-файлы
├── hv-sql-01-Data.vhdx -> доступен для hv-sql-01 как D: (данные)
└── hv-sql-01-Log.vhdx -> доступен для hv-sql-01 как L: (журнал)
└── SQL Server: TPCC-4T
Цель восстановления — hv-sql-02, у которого есть свой собственный CSV (Cluster Disk 11), расположенный на отдельном томе FlashArray с именем hyperv-csv-01-DATA-DEV. Мы собираемся перезаписать целевой том клоном производственного снимка, а затем подключить базу данных на SQL Server 02.
Важный момент: и VHDX с данными, и VHDX с журналом находятся на одном томе FlashArray, который также является одним CSV. Один снимок тома захватывает оба файла в одну и ту же согласованную картину. Поэтому мы используем New-Pfa2VolumeSnapshot непосредственно для тома, а не снимок группы защиты (Protection Group snapshot), охватывающий несколько томов. Если ваши VHDX-файлы находятся в разных CSV на разных томах FlashArray, они ДОЛЖНЫ быть помещены в одну Protection Group, чтобы это работало правильно.
Инициализация переменных и подключений в скрипте PowerShell
Для начала давайте настроим переменные PowerShell. Я использую модули dbatools и Pure Storage PowerShell SDK2.
Import-Module dbatools
Import-Module PureStoragePowerShellSDK2
$SourceSQLServer = 'hv-sql-01' # SQL Server, содержащий исходную базу данных
$TargetSQLServer = 'hv-sql-02' # SQL Server, который получит клон
$ArrayName = 'flasharray1.fsa.lab' # Конечная точка FlashArray
$DbName = 'TPCC-4T' # Имя базы данных
$HVNode2 = 'sql-fci-02.fsa.lab' # Узел кластера Hyper-V, владеющий целевым CSV
$TargetCSVResource = 'Cluster Disk 11' # Имя ресурса кластера для целевого CSV
$SourceVolName = 'hyperv-csv-01-DATA-PROD' # Том FA, лежащий в основе исходного CSV
$TargetVolName = 'hyperv-csv-01-DATA-DEV' # Том FA, лежащий в основе целевого CSV
$ClonedDataVhdx = 'C:\ClusterStorage\Volume11\hv-sql-01\hv-sql-01-Data.vhdx'
$ClonedLogVhdx = 'C:\ClusterStorage\Volume11\hv-sql-01\hv-sql-01-Log.vhdx'
$DataCtrlNum = 0; $DataCtrlLoc = 1 # VHDX с данными на SCSI 0:1
$LogCtrlNum = 0; $LogCtrlLoc = 2 # VHDX с журналом на SCSI 0:2
Построение подключений
Мне нужны три подключения: сеанс удалённого управления PowerShell (PowerShell remoting session) к узлу кластера Hyper-V, подключения к обоим экземплярам SQL Server и сеанс к REST API FlashArray. Вам не обязательно использовать dbatools для подключения к SQL Server, но я рекомендую это — так проще.
$HVSession = New-PSSession -ComputerName $HVNode2
$SqlInstance1 = Connect-DbaInstance -SqlInstance $SourceSQLServer -TrustServerCertificate -NonPooledConnection
$SqlInstance2 = Connect-DbaInstance -SqlInstance $TargetSQLServer -TrustServerCertificate -NonPooledConnection
$FACred = Import-CliXml -Path "$HOME\FA_Cred.xml"
$FlashArray = Connect-Pfa2Array -EndPoint $ArrayName -Credential $FACred -IgnoreCertificateError
$HVSession — это сеанс удалённого управления узлом Hyper-V, и мы будем использовать его для управления ресурсами CSV и подключениями VHDX на уровне гипервизора.
Давайте быстро посмотрим на исходную базу данных, прежде чем что-либо делать.
Get-DbaDatabase -SqlInstance $SqlInstance1 -Database $DbName |
Select-Object Name, SizeMB, Status
Name SizeMB Status
---- ------ ------
TPCC-4T 4043579.50 Normal
Создание аварийно-устойчивого снимка
Теперь создадим снимок. Исходный SQL Server продолжает работать без каких-либо прерываний. Мы не просим его ничего делать.
Примечание о кэше CSV Hyper-V: Если в вашем кластере Hyper-V включён кэш записи CSV, данные записи могут находиться в памяти хоста, прежде чем быть сброшены на том FlashArray. Снимок FlashArray захватывает то, что находится на томе, а не то, что в кэше. Если кэш CSV отключён (что является лучшей практикой при использовании высокопроизводительных хранилищ, таких как FlashArray), это не проблема. Если он включён, выполните Checkpoint-VM (Production Checkpoint) перед созданием снимка, чтобы сначала сбросить кэш.
$Start = (Get-Date)
$Snapshot = New-Pfa2VolumeSnapshot -Array $FlashArray -SourceName $SourceVolName
$Snapshot
Id : 9c7ab79a-afbd-0279-2fcf-3648e03a2647
Name : hyperv-csv-01-DATA-PROD.17
Created : 5/8/2026 5:04:41 PM
Destroyed : False
Source : @{Id='73cc51e1-b7a7-6000-d3f1-f3e4b19fd030'; Name='hyperv-csv-01-DATA-PROD'}
Suffix : 17
New-Pfa2VolumeSnapshot выполняется мгновенно с точки зрения массива. Имя снимка возвращается с суффиксом (.17 в данном случае), добавленным к имени исходного тома. Оба VHDX на этом CSV захватываются одной атомарной операцией.
Я устанавливаю $Start перед созданием снимка, чтобы тайминг включал полную последующую последовательность восстановления хранилища.
Подготовка SQL 02 к клону
Прежде чем мы сможем заняться манипуляциями хранилища, нам нужно устранить влияние SQL Server на целевой стороне. SQL Server держит открытые дескрипторы файлов томов, поддерживаемых VHDX. Нам не нужно останавливать SQL Server. Нам нужно просто перевести пользовательские базы данных в режим OFFLINE, чтобы их дескрипторы файлов были освобождены. Имейте в виду, если бы вы делали это с помощью резервного копирования/восстановления, базы данных были бы недоступны на всё время восстановления.
$Query = "ALTER DATABASE [$DbName] SET OFFLINE WITH ROLLBACK IMMEDIATE"
Invoke-DbaQuery -SqlInstance $SqlInstance2 -Query $Query
Только пользовательские базы данных, которые я хочу обновить, должны перейти в режим OFFLINE. Системные базы данных (master, msdb, model, tempdb) не трогаются.
Последовательность операций с Hyper-V хранилищем
Это та часть, которая отличается от восстановления из снимка на «голом» сервере (bare-metal snapshot restore). На «голом» сервере замена хранилища — это просто «отключить диск, клонировать, подключить диск». В среде Hyper-V с CSV слоёв больше: VHDX-файлы подключены к виртуальной машине на уровне гипервизора, а CSV является ресурсом кластера. Нам нужно разобрать эти слои, прежде чем мы сможем заменить том, а затем восстановить их после этого.
Последовательность действий:
- Отключить VHDX от целевой виртуальной машины.
- Перевести ресурс кластера CSV в режим
OFFLINE. - Клонировать снимок на целевой том.
- Включить ресурс кластера CSV (
ONLINE). - Повторно подключить VHDX к целевой виртуальной машине.
Отключение VHDX от целевой виртуальной машины
Мы выполняем это через $HVSession — сеанс удалённого управления узлом Hyper-V. Мы, по сути, отключаем виртуальные жёсткие диски от виртуальной машины, потому что собираемся обновить их содержимое из снимка. Имейте в виду, что любые файлы на этих VHDX недоступны в течение этого времени. Поэтому при проектировании топологии файлов базы данных планируйте соответственно.
Invoke-Command -Session $HVSession -ScriptBlock {
Remove-VMHardDiskDrive -VMName 'hv-sql-02' -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 1
Remove-VMHardDiskDrive -VMName 'hv-sql-02' -ControllerType SCSI -ControllerNumber 0 -ControllerLocation 2
}
Перевод CSV в режим OFFLINE
Том FlashArray не может быть перезаписан, пока кластер использует его как активный CSV. Stop-ClusterResource корректно переводит его в режим OFFLINE. Имейте в виду, что всё, что находится в этом CSV, будет недоступно в течение этого времени. Поэтому при проектировании топологии хранилища планируйте соответственно.
Invoke-Command -Session $HVSession -ScriptBlock {
param($res)
Stop-ClusterResource -Name $res -Cluster (Get-Cluster).Name | Out-Null
Write-Output "$res offline"
} -ArgumentList $TargetCSVResource
# Вывод: Cluster Disk 11 offline
Клонирование снимка на целевой том
Это момент, когда выполняется реальная работа, и он почти мгновенный. New-Pfa2Volume с параметром -Overwrite $true перезаписывает целевой том в точное состояние, зафиксированное в снимке. На Pure Storage FlashArray это операция только над метаданными: никакие данные физически не копируются, независимо от того, насколько велик том. Том объёмом 10 ТБ перезаписывается за то же время, что и том объёмом 10 ГБ, а также том объёмом 10 КБ.
New-Pfa2Volume -Array $FlashArray -Name $TargetVolName -SourceName $Snapshot.Name -Overwrite $true
Id : d7e39f69-fefc-8578-5a9f-cc5b87981952
Name : hyperv-csv-01-DATA-DEV
Source : @{Id='73cc51e1-b7a7-6000-d3f1-f3e4b19fd030'; Name='hyperv-csv-01-DATA-PROD'}
Включение CSV и повторное подключение VHDX
Возвращаем ресурс кластера в режим ONLINE. Кластер перемонтирует теперь уже клонированный том.
Invoke-Command -Session $HVSession -ScriptBlock {
param($res)
Start-ClusterResource -Name $res -Cluster (Get-Cluster).Name | Out-Null
Write-Output "$res online"
} -ArgumentList $TargetCSVResource
# Вывод: Cluster Disk 11 online
Подождите несколько секунд, пока CSV смонтируется, затем повторно подключите VHDX на тех же контроллерах и позициях SCSI.
Start-Sleep -Seconds 5
Invoke-Command -Session $HVSession -ScriptBlock {
param($dataVhdx, $logVhdx, $dCN, $dCL, $lCN, $lCL)
Add-VMHardDiskDrive -VMName 'hv-sql-02' -Path $dataVhdx -ControllerType SCSI -ControllerNumber $dCN -ControllerLocation $dCL
Add-VMHardDiskDrive -VMName 'hv-sql-02' -Path $logVhdx -ControllerType SCSI -ControllerNumber $lCN -ControllerLocation $lCL
} -ArgumentList $ClonedDataVhdx, $ClonedLogVhdx, $DataCtrlNum, $DataCtrlLoc, $LogCtrlNum, $LogCtrlLoc
Ввод базы данных в режим ONLINE на SQL 02
Теперь, когда хранилище на месте, нам просто нужно перевести базу данных обратно в режим ONLINE. Мы перевели её в режим OFFLINE в начале скрипта, чтобы освободить дескрипторы файлов перед заменой хранилища. Теперь, когда клонированный том смонтирован, а VHDX повторно подключены, достаточно одной команды SET ONLINE.
$Query = "ALTER DATABASE [$DbName] SET ONLINE"
Invoke-DbaQuery -SqlInstance $SqlInstance2 -Query $Query
Write-Output "$DbName is online on $TargetSQLServer"
# Вывод: TPCC-4T is online on hv-sql-02
Когда SQL Server переводит базу данных в режим ONLINE, он обнаруживает, что файлы отражают незапланированное завершение работы. Он автоматически запускает аварийное восстановление (crash recovery): накатывает зафиксированные транзакции из журнала, откатывает всё, что находилось в процессе выполнения, и переводит базу данных в режим ONLINE. Вы не выполняете никакой команды RESTORE. Вам не нужна резервная копия журнала. SQL Server просто справляется сам.
Проверка конечного состояния
Get-DbaDbState -SqlInstance $SqlInstance2 -Database $DbName
Access : MULTI_USER
ComputerName : hv-sql-02
DatabaseName : TPCC-4T
InstanceName : MSSQLSERVER
RW : READ_WRITE
SqlInstance : hv-sql-02
Status : ONLINE
Get-DbaDatabase -SqlInstance $SqlInstance2 -Database $DbName | Select-Object Name, Status, SizeMB
Name SizeMB Status
---- ------ ------
TPCC-4T 4043579.50 Normal
TPCC-4T находится в режиме ONLINE, READ_WRITE и показывает правильный размер на hv-sql-02.
Сколько времени это заняло?
$Stop = (Get-Date)
Write-Output "Total time from snapshot to database online: $(($Stop - $Start).Seconds) seconds"
# Вывод: Total time from snapshot to database online: 25 seconds
25 секунд от создания снимка до живой, полностью восстановленной клонированной базы данных на тестовом SQL Server. Исходный SQL Server работал без перерыва на протяжении всего процесса. Вот как выглядит обновление базы данных с помощью снимков, когда основную работу выполняет хранилище.
Очистка
Remove-PSSession $HVSession
Disconnect-Pfa2Array -Array $FlashArray
Write-Output "Session and FlashArray connection closed."
# Вывод: Session and FlashArray connection closed.
Резюме
Вот что произошло за эти 25 секунд:
| Шаг | Время |
|---|---|
| Создание аварийно-устойчивого снимка тома | мгновенно |
| Перевод пользовательских БД в OFFLINE на SQL 02 | ~1 сек |
| Отключение VHDX от виртуальной машины | ~2 сек |
| Перевод ресурса кластера CSV в OFFLINE | ~2 сек |
| Клонирование снимка на целевой том (операция с метаданными) | мгновенно |
| Включение ресурса кластера CSV (ONLINE) | ~3 сек |
| Повторное подключение VHDX к виртуальной машине | ~5 сек |
| ALTER DATABASE SET ONLINE + аварийное восстановление | ~5 сек |
Само клонирование на FlashArray по сути занимает нулевое время: это замена указателя на метаданные. Остальное время — это операции Windows и кластера Hyper-V: монтирование CSV, представление виртуальных дисков гостевой ОС и проход аварийного восстановления SQL Server по журналу.
Сравните это с традиционным циклом обновления через резервное копирование и восстановление: передача полной резервной копии по сети, её восстановление на целевом сервере. Для многогигабайтной базы данных это могут быть часы. При клонировании снимка это всегда измеряется секундами, независимо от размера базы данных.
Когда следует использовать аварийно-устойчивый снимок против согласованного на уровне приложения?
| Аспект | Аварийно-устойчивый (Crash-Consistent) | Согласованный на уровне приложения (Application-Consistent) |
|---|---|---|
| Воздействие на исходный SQL Server | Отсутствует | Задержка записи (write freeze) в миллисекунды |
| Тип снимка | Только на уровне хранилища | Хранилище + резервная копия метаданных SQL Server |
| Возможность восстановления на момент времени (PITR) | Нет | Да (с цепочкой резервных копий журнала) |
| Процесс восстановления | SET ONLINE + автоматическое аварийное восстановление | RESTORE WITH METADATA_ONLY + RESTORE LOG |
| Лучшее применение | Обновление dev/test или отчётности, клонирование | Производственное резервное копирование, PITR |
Если вам нужно восстановление на момент времени или вы хотите получить правильную запись в msdb о резервном копировании SQL Server, которая хорошо работает с вашей существующей автоматизацией восстановления, используйте подход T-SQL Snapshot Backup, описанный в остальной части этой серии. Если вам просто нужно максимально быстрое обновление базы данных на сервере разработки/тестирования или отчётности, и вам не нужен PITR, аварийно-устойчивый снимок — правильный инструмент для этой задачи.
Подведение итогов
Клонирование аварийно-устойчивых снимков позволяет перейти от производственных данных к обновлённой базе данных для разработки/тестирования или отчётности менее чем за минуту с нулевым воздействием на исходный SQL Server. Само клонирование на FlashArray — это замена указателя на метаданные, занимающая фактически нулевое время, независимо от размера базы данных. Остальное время — это операции Windows и кластера Hyper-V.
Ключевые выводы из этой статьи:
- Аварийно-устойчивый снимок не требует никакой координации со стороны SQL Server — никакой заморозки, никакого прерывания операций записи на исходном сервере.
- Оба VHDX захватываются атомарно, поскольку файлы данных и журналов находятся на одном томе FlashArray, один вызов
New-Pfa2VolumeSnapshotзахватывает их в согласованном состоянии. - Если вам нужно восстановление на момент времени (PITR) — обратитесь к статьям серии T-SQL Snapshot Backup. Статья Использование T-SQL Snapshot Backup — редакция Hyper-V описывает полный согласованный на уровне приложения рабочий процесс с
SUSPEND_FOR_SNAPSHOT_BACKUPи восстановлением из журналов на момент времени.

Комментариев нет:
Отправить комментарий