Короткий ответ
Сначала разделите три вещи: (1) dynamic VHDX дорос до своего максимума (Size в Get-VHD), (2) рядом лежит цепочка .avhdx от checkpoint/backup, (3) забиты логи/ISO/хостовый dump, а не диск гостя. На C:\ClusterStorage\Volume1 удаление «большого vhdx» в Explorer — это уничтожение VM-APP01.
Compact (Optimize-VHD) не освободит том, пока внутри гостя не обнулили свободное место и пока висят checkpoint. Compact на работающей VM или на differencing — путь к порче.
Симптомы и как отличить
Типичная картина:
- CSV
Volume1красный, VM падают в Saved; - в каталоге VM файл
VM-APP01.vhdx+ несколько*.avhdx; - в госте «диск C: свободен», на хосте файл всё равно большой — так и должен dynamic после записи;
- backup породил production checkpoint и не слил.
Отличия:
| Что видно | Куда |
|---|---|
| Нужно штатно сжать после очистки гостя | уменьшить VHDX |
| Delete checkpoint не идёт | checkpoint |
| Диск не цепляется | VHDX не подключается |
| Latency, не место | нагрузка диска |
Возможные причины
- Dynamic диск с потолком 2 ТБ на томе 800 ГБ: гость записал данные, файл догнал том.
- Checkpoint/Replica/backup оставили AVHDX; сумма цепочки > свободного места.
- Забыли ISO, export, старые копии
VM-APP01-copy.vhdxна том же CSV. - Smart paging / Saved State
.binразрослись при нехватке RAM. - Hyper-V Replica initial copy на тот же том.
- Fixed VHDX изначально занял Size целиком — это не «рост», это тип диска.
Диагностика
Get-Volume | Format-Table DriveLetter, FileSystemLabel, FileSystem, @{N='FreeGB';E={[math]::Round($_.SizeRemaining/1GB,1)}}, @{N='SizeGB';E={[math]::Round($_.Size/1GB,1)}}
Get-ChildItem -Path 'C:\ClusterStorage\Volume1' -Recurse -ErrorAction SilentlyContinue |
Sort-Object Length -Descending | Select-Object -First 30 FullName, @{N='GB';E={[math]::Round($_.Length/1GB,2)}}По VM:
Get-VMHardDiskDrive -VMName 'VM-APP01' | ForEach-Object {
Get-VHD -Path $_.Path | Select-Object Path, VhdType, @{N='FileGB';E={[math]::Round($_.FileSize/1GB,2)}}, @{N='MaxGB';E={[math]::Round($_.Size/1GB,2)}}, ParentPath
}
Get-VMCheckpoint -VMName 'VM-APP01'
Get-ChildItem 'C:\ClusterStorage\Volume1\VM-APP01' -Filter *.avhdxVhdType : Differencing + ParentPath — вы смотрите не на «раздутый базовый диск», а на overlay. Место ест overlay + родитель.
Реплика и backup:
Get-VMReplication -VMName 'VM-APP01' -ErrorAction SilentlyContinue
Get-VM -Name 'VM-APP01' | Format-List CheckpointFileLocation, SnapshotFileLocation, SmartPagingFilePathРешение
Сценарий A. Мусор на CSV, не диск гостя
Удалите ISO, старые Export, Copy of VM-APP01.vhdx, дампы MEMORY.DMP хоста. Не трогайте текущий Path из Get-VMHardDiskDrive.
Сценарий B. Checkpoint / AVHDX
Штатно удалите ненужные checkpoint в Hyper-V / Failover Cluster — это запустит merge. Дождитесь Get-StorageJob / исчезновения лишних avhdx. Если merge не идёт — статьи про checkpoint и AVHDX, не Disk Cleanup.
Production checkpoint от backup, который «залип»: дождитесь окончания job или разберите writer; не сносите recovery snapshot из Explorer.
Сценарий C. Dynamic дорос до Size, том хоста кончился
Варианты, не взаимозаменяемые:
- Расширить CSV/том (хранилище), если гостю данные нужны.
- Перенести VM на больший том (
Move-VMStorage). - В госте почистить данные, затем сжать VHDX в окно простоя — только после backup.
- Не «увеличить Size» если физически том меньше нового максимума — получите мгновенный 0 байт при следующей записи.
Расширение логического диска без места на CSV бессмысленно. Сначала хранилище, потом Resize-VHD.
Сценарий D. Saved State и paging
Перенесите SmartPagingFilePath на том с местом или освободите RAM (не держите десяток VM в Saved). Delete Saved State — только с пониманием потери памяти гостя.
Сценарий E. Fixed диск «съел всё с первого дня»
Это норма FileSize = Size. Лечение — другой том или конвертация в dynamic с местом и backup, не compact fixed тем же смыслом что dynamic.
Get-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' | Format-List VhdType, FileSize, SizeКак проверить, что проблема устранена
Get-Volume -FileSystemLabel 'Volume1' | Format-List SizeRemaining, Size
Get-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' | Format-List FileSize, Size, VhdType, ParentPath
Get-VM -Name 'VM-APP01' | Format-List State
Get-VMCheckpoint -VMName 'VM-APP01'Свободные гигабайты на CSV с запасом под рост и merge. VM Running. Лишних checkpoint нет, либо они осознанные. Гость пишет данные без паузы Hyper-V «not enough space».
Если не помогло
- Место освободили, VM всё равно не стартует: старт.
- После compact гость в RAW: вы сжимали с checkpoint или без обнуления — restore из backup, не chkdsk хоста по VHDX.
- Replica забивает второй том: ограничьте initial replication расписанием, не тем же CSV что прод-IO.
- SQL в госте пишет тоннами в dynamic: планируйте Size и мониторинг FileSize, не «поставили 4 ТБ на всякий».
Профилактика
- Алерт на свободное место CSV и на FileSize/Size ratio.
- Запрет долгих production checkpoint.
- Dynamic потолок не больше осмысленного объёма тома.
- Отдельный том под Replica/backup.
- Регулярный отчёт
Get-VHDпо всем VM наHV01.
FAQ
Почему в госте удалили 100 ГБ, а на хосте файл не уменьшился?
Dynamic VHDX не сжимается от Delete в NTFS гостя. Нужны обнуление свободного места и Optimize-VHD при Off, см. сжатие VHDX.
Можно ли Convert в dynamic на месте чтобы освободить?
Convert пишет новый файл. Нужно свободное место ≈ размера данных. На забитом томе Convert не старт, а финиш.
Checkpoint «на час» опасен для места?
Да. Overlay растёт со скоростью записи гостя. На busy SQL час — десятки гигабайт AVHDX плюс место под последующий merge.
Thin на SAN и dynamic VHDX — двойной thin?
Да, и оба могут внезапно закончиться. Мониторьте и SAN, и FileSize.
Стоит ли сразу ставить Fixed?
Предсказуемое место, хуже по начальному занятому объёму. Для прод-БД часто Fixed или dynamic с потолком и алертом. Не догма.
Удалить $Recycle.Bin на CSV?
Корзина хоста может держать гигабайты. Очистка Recycle Bin хоста на CSV допустима, если это не единственная копия VHDX. Не путать с удалением файлов VM.