Короткий ответ
AVHDX — overlay. Текущие блоки гостя часто живут в самом новом differencing-файле. Цель — штатный Merge-VHD / добить checkpoint, чтобы VM снова ссылалась на один VHDX. Ручное удаление любого файла цепочки = дырки в диске гостя.
Снимите карту ParentPath от листа к корню, убедитесь что VM Off и никто не держит файлы, сделайте копию всей папки, затем merge от самого дочернего к родителю — как в документации Merge-VHD, не «все сразу».
Симптомы и как отличить
Типичная картина:
Get-VHDна текущем диске VM:VhdType : Differencing, ParentPath заполнен;- ошибка broken chain при Start-VM;
- после сбоя backup два recovery overlay;
- StorageJob Merge в Failed.
Отличия:
| Что видно | Куда |
|---|---|
| GUI Delete ещё должен работать | checkpoint не удаляется |
| Файл просто lock | VHDX не подключается |
| Backup держит VSS | зависание backup |
| Merge живой но вечный из-за IO | нагрузка диска |
Возможные причины
- Не хватило места, merge оборвался, конфиг VM уже смотрит не туда.
- Переименовали/переместили родителя в Explorer.
- Одновременно backup, replica и ручной checkpoint.
- Подключили средний avhdx как диск VM.
- Смешали merge GUI и Merge-VHD.
- Антивирус открыл файл на запись посередине.
Диагностика
Get-VM -Name 'VM-APP01' | Format-List State, Id, Path
Get-VMHardDiskDrive -VMName 'VM-APP01' | Format-Table Path, ControllerType
Get-VMCheckpoint -VMName 'VM-APP01' | Format-Table Name, SnapshotType, PathКарта цепочки (повторите для каждого avhdx):
$leaf = (Get-VMHardDiskDrive -VMName 'VM-APP01').Path | Select-Object -First 1
$cur = $leaf
while ($cur) {
$h = Get-VHD -Path $cur
[pscustomobject]@{ Path = $h.Path; Type = $h.VhdType; Parent = $h.ParentPath; FileGB = [math]::Round($h.FileSize/1GB,2) }
$cur = $h.ParentPath
}
Test-VHD -Path $leafЕсли Get-VHD на ParentPath бросает «cannot find», цепочка порвана: ищите файл по имени в backup/Volume Shadow, не создавайте пустой VHDX с тем же именем.
Get-StorageJob -ErrorAction SilentlyContinue
Get-ClusterSharedVolume
Get-Volume | Format-Table DriveLetter, FileSystemLabel, SizeRemainingРешение
Сценарий A. Дерево checkpoint целое
Не ходите в Merge-VHD. Вернитесь к Remove-VMCheckpoint. Эта статья — когда GUI/cmdlet снимка уже не могут.
Сценарий B. VM Off, цепочка целая, GUI мёртв
- Скопируйте каталог
C:\ClusterStorage\Volume1\VM-APP01на другой том (все vhdx/avhdx/xml). - Отключите диск от VM (настройки SCSI), чтобы Path не держал файл, либо оставьте Off и работайте осторожно: Merge-VHD требует, чтобы целевые файлы не были в exclusive use другой VM.
Stop-VM -Name 'VM-APP01'
# снимите диск из конфигурации только если Merge-VHD ругается на in use- Слейте лист в родителя. Пример: текущий диск
data.avhdx, родительdata.vhdx:
Merge-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.avhdx' -DestinationPath 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx'-DestinationPath должен быть непосредственным родителем этого avhdx, не «самый нижний файл, который вспомнили». Для длинной цепочки повторяйте от листа к корню по одному шагу, каждый раз проверяя Get-VHD.
- Верните Path VM на получившийся VHDX:
Get-VMHardDiskDrive -VMName 'VM-APP01' |
Set-VMHardDiskDrive -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx'
Start-VM -Name 'VM-APP01'Сценарий C. Обрыв ParentPath
Восстановите недостающий файл из backup в тот же путь, что ждёт ParentPath, либо Set-VHD -Path leaf -ParentPath 'D:\restored\parent.vhdx' только если это действительно тот родитель (тот же идентификатор цепочки). Угадывание родителя по размеру файла — порча.
Сценарий D. Два overlay от backup
Оставьте VM Off. Разберите, какой avhdx сейчас в Get-VMHardDiskDrive. Лишние recovery, на которые никто не ссылается (ни VM, ни ParentPath), можно убрать после доказательства, что на них нет ссылок — и то лучше оставить в архиве заявки.
Сценарий E. Merge-VHD падает на месте
Нет места, lock, read-only. Снимите Read-only, исключите антивирус на время окна, освободите CSV. Не -Force из примеров форумов, если не понимаете параметр вашей версии.
Как проверить, что проблема устранена
Test-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx'
Get-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' | Format-List VhdType, ParentPath, FileSize
Get-VMHardDiskDrive -VMName 'VM-APP01'
Get-VM -Name 'VM-APP01' | Format-List StateParentPath пуст, Test-VHD без ошибки, гость грузится, приложения видят свежие данные (не откат на дату снимка). Сверьте дату файлов в госте.
Если не помогло
- После merge старые данные: вы слили не тот лист — откат к копии каталога, сделанной до Merge-VHD.
- VM не стартует: диск и старт.
- Экспорт всё ещё видит дерево: экспорт.
- Цепочка на ReFS/CSV в redirected: сначала storage health.
Не используйте сторонние «VHDX repair» на единственной копии.
Профилактика
- Не трогать avhdx руками.
- Не копить снимки.
- Backup job обязан завершать Hyper-V checkpoint.
- Перед ручным Merge-VHD — копия цепочки и окно простоя.
- Документировать Path диска в заявке до любой операции.
FAQ
Чем Merge-VHD отличается от Remove-VMCheckpoint?
Remove знает дерево снимков Hyper-V (XML, память, конфиг). Merge-VHD сливает только два VHD. После ручного merge конфиг VM и checkpoint metadata могут разъехаться — поэтому это аварийный путь.
Можно ли merge при Running?
Живой merge делает сам Hyper-V через checkpoint API. Ручной Merge-VHD — для Offline дисков. Не смешивайте.
DestinationPath — это куда «результат»?
Для Merge-VHD это родитель, в которого вливается дочерний. Дочерний после успеха обычно становится ненужным overlay. Проверьте документацию вашей версии и Get-VHD после операции, прежде чем удалять исходный avhdx.
Set-VHD -IgnoreIdMismatch?
Это когда сознательно подставляют родителя с другим ID. На прод почти всегда запрещено. Ломает связь differencing.
Нужен ли Convert-VHD вместо merge?
Convert копирует цепочку в новый плоский диск. Нужно много места. Запасной путь, если merge нестабилен и есть куда писать.
Почему Test-VHD зелёный, а гость BSOD?
Цепочка файлов валидна, но вы подключили не тот лист (старый avhdx). Смотрите Path в VM, не «какой файл больше».