Короткий ответ

Уменьшение бывает двух разных операций: (1) compact dynamic VHDX (Optimize-VHD) — схлопывает незанятые блоки файла на хосте; (2) shrink логического Size (Resize-VHD вниз) — только после сжатия раздела в госте ниже нового потолка. Обе требуют Off (для compact — обязательно), отсутствие checkpoint и проверенный backup.

Удаление файлов в госте само по себе FileSize не уменьшает: блоки в VHDX остаются «грязными», пока не TRIM/zero и compact.

Симптомы и как отличить

Типичная картина:

  • в госте свободно 200 ГБ, на CSV файл 500 ГБ;
  • после Disk Cleanup FileSize тот же;
  • Optimize-VHD мгновенно «готов» без изменения Length.

Отличия:

Что видноКуда
Нужно вырастить дискрасширить
Том хоста съел dynamic/AVHDXрост
Мешают снимкиcheckpoint, merge
Просто latencyнагрузка диска

Возможные причины

  1. Checkpoint/differencing.
  2. VM Running / Attached.
  3. В госте не обнулили свободное (нет TRIM на этом стеке, NTFS дырки).
  4. Optimize-VHD -Mode Quick недостаточно, нужен Full (дольше).
  5. Pagefile, гибернация, теневые копии гостя держат блоки.
  6. ReFS/CSV особенности — всё равно Off и backup.

Диагностика

Get-VM -Name 'VM-APP01' | Format-List State
Get-VMCheckpoint -VMName 'VM-APP01'
Get-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' | Format-List VhdType, Size, FileSize, MinimumSize, ParentPath, FragmentationPercentage, Attached
Get-Volume | Format-Table DriveLetter, FileSystemLabel, SizeRemaining

MinimumSize подскажет, ниже какого Size Resize не пойдёт, пока не урежете раздел гостя.

В госте: свободное место тома, fsutil volume diskfree C:, теневые копии, размер pagefile.

Решение

Подготовка (обязательна)

  1. Backup / export / СХД-снимок, который вы умеете откатить.

  2. Слить checkpoint.

  3. В госте: удалить ненужное, выключить гибернацию, уменьшить pagefile если он раздут, очистить shadow copies осознанно.

  4. Обнуление свободного места: для NTFS часто Optimize-Volume / TRIM (Retrim), либо утилита zero-fill если TRIM до VHDX не доходит. На SSD/thin с unmap достаточно Retrim; на старых стеках — sdelete -z (Sysinternals) в окно. Не zero-fill на уже задыхающемся CSV без запаса (временно займёт место).

  5. Штатное выключение гостя:

Stop-VM -Name 'VM-APP01'
Get-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' | Format-List Attached

Attached должен быть False.

Compact dynamic

Optimize-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' -Mode Full
Get-Item 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' | Format-List Length
Get-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' | Format-List FileSize, Size

Сравните FileSize до/после. Full читает весь диск — время и IO.

Shrink логического Size (редко)

Только если раздел гостя уже меньше цели:

# VM Off, раздел в госте уже сжат заранее при Running через Disk Management Shrink
Resize-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' -ToMinimumSize
# или -SizeBytes явно, не меньше MinimumSize

Порядок строго: shrink partition в госте → Off → Resize-VHD вниз. Обратный порядок режет данные.

Convert Fixed → Dynamic

Convert-VHD -Path 'D:\old\disk.vhdx' -DestinationPath 'D:\new\disk-dynamic.vhdx' -VHDType Dynamic

Нужно свободное место под новый файл. Потом переключить Path VM, проверить старт, удалить старый после проверки.

Запишите FileSize до операции. Без цифры «вроде сжалось» нельзя закрыть заявку. Если Full пробежал за секунды на 400 ГБ диске — он не читал диск, файл был locked или тип не dynamic.

Не путайте Optimize-VHD с Optimize-Volume в госте (дефраг/retrim NTFS). Второе готовит блоки, первое схлопывает файл хоста. Порядок: гость Retrim/zero → Off → Optimize-VHD. Обратный порядок бесполезен.

На CSV не запускайте compact двух многотерабайтных VM параллельно: временный метаданный рост и очередь диска уронят соседей. Одна VM за окно.

После compact обязательно Start и проверка приложения, затем — и только затем — удаление backup-копии «на всякий», если политика хранения позволяет. Неделю держать копию дешевле, чем restore через месяц.

MinimumSize после shrink раздела в госте должен упасть. Если не упал — раздел не уменьшили или VM ещё держала диск. Не Resize-VHD вниз против MinimumSize.

Как проверить, что проблема устранена

Start-VM -Name 'VM-APP01'
Get-VM -Name 'VM-APP01' | Format-List State, Heartbeat
Get-VHD -Path 'C:\ClusterStorage\Volume1\VM-APP01\VM-APP01.vhdx' | Format-List FileSize, Size, VhdType

Гость консистентен: логон, chkdsk не обязателен если не было Turn Off. Приложения видят данные. FileSize снизился ожидаемо. CSV свободнее. После суток записи FileSize не обязан остаться минимальным — dynamic снова вырастет.

Если не помогло

  • FileSize не изменился: checkpoint остался, Running, не было zero/TRIM, или диск Fixed.
  • Гость raw/не грузится: restore из backup, не второй compact.
  • CSV кончился во время Full: места не хватило на рабочий файл — restore.
  • Высокая фрагментация без выигрыша места — compact не дефраг гостя.

Профилактика

  • Не копить мусор в госте на dynamic «потому что thin».
  • Алерт FileSize vs содержимое.
  • Compact — редкая плановая операция, не weekly на OLTP.
  • Checkpoint не держать.
  • TRIM из гостя, если СХД/Hyper-V unmap включены по вашей схеме.
  • Compact не замена расширению CSV. Если гостю данные нужны, место на Volume1 всё равно понадобится при следующем росте FileSize.
  • Запретите Optimize-VHD в скриптах без проверки Get-VMCheckpoint и State -eq Off.

FAQ

Quick vs Full?

Quick быстрее и слабее. Full — полный проход. Для «удалили 200 ГБ» обычно Full после zero/TRIM.

Можно ли compact с Mount-VHD?

Официальный путь — Optimize-VHD при отключённом диске от VM. Не монтируйте прод и не пишите с хоста в NTFS гостя.

sdelete обязателен?

Нет, если unmap работает. Если FileSize не падает после Retrim+Full — тогда zero-fill в окно.

Уменьшит ли compact Size (потолок)?

Нет, только FileSize. Потолок — Resize-VHD после shrink раздела.

ReFS в госте?

Свои правила TRIM. Не переносите NTFS-ритуал слепо. Backup обязателен тем более.

Почему Microsoft советует Off?

Метаданные VHDX и открытые записи. Compact live официально не ваш сценарий прод-починки.