АйТи Фреш
Главная / Статьи / Серверы и инфраструктура
Серверы и инфраструктура

Добавили памяти виртуалке — она перестала включаться: сколько места на datastore съедает .vswp

Автор: Семёнов Евгений Сергеевич, директор ООО «АйТи-Фреш» · · ~19 мин чтения
Добавление памяти ВМ раздувает файл .vswp и забирает свободное место на datastore ESX 9
Каждый добавленный гигабайт незарезервированной памяти — это гигабайт на датасторе в момент включения.

Если виртуалка перестала включаться сразу после добавления памяти, почти наверняка ей не хватило места под файл подкачки .vswp: ESX создаёт его при включении размером «память минус резервирование». Ниже — как это посчитать заранее, где держать свопы и почему резервирование памяти лечит одно, но ломает другое.

Почему ВМ не включается после добавления памяти

Сценарий повторяется у меня из года в год почти дословно, и в рамках ИТ-аутсорсинга для небольших компаний я разбираю его чаще, чем хотелось бы. Плановое окно, сервер 1С тормозит, бизнес просит «дайте памяти». Админ выключает ВМ, в Edit Settings меняет 24 ГБ на 64 ГБ, жмёт OK — и машина обратно не поднимается. vCenter отдаёт что-то из семейства «Insufficient disk space on datastore», в vmware.log виртуалки лежит честное «No space left on device». Дальше начинается тупик: человек смотрит на VMDK — 300 ГБ, как и был; снапшотов нет; внутри гостя ничего не распухло. Связь между «добавил RAM» и «кончилось место на диске» в голове не выстраивается, потому что интуитивно память и дисковое пространство — разные ресурсы.

Причина укладывается в одну строчку, и она прямо написана в Performance Best Practices for VMware vSphere 9.0: при включении виртуальной машины ESX создаёт для неё файл подкачки, равный по размеру разнице между сконфигурированным объёмом памяти и её резервированием памяти. Доступного места на диске должно быть как минимум столько же — плюс место под VMX swap. То есть при нулевом резервировании (а оно нулевое по умолчанию) 24-гигабайтная ВМ требовала 24 ГБ свободного места на датасторе, а 64-гигабайтная требует 64 ГБ. Вы не трогали диск — вы подняли требование к свободному месту на 40 ГБ. А если файл создать не удалось, документация vSphere формулирует итог коротко: виртуальная машина не включится.

Отдельно объясню, почему днём всё работало, а вечером сломалось. Пока ВМ включена, её .vswp существует и место держит. Как только вы выключили машину на обслуживание, файл удалился и 24 ГБ вернулись в общий котёл — где их немедленно разобрали соседние ВМ, растущие тонкие диски и бэкапные снапшоты. Обратно вы просите уже не 24, а 64 ГБ, и их там нет. Отсюда фирменный вывод «до перезагрузки же работало», который уводит расследование совсем не туда.

Ещё одна ловушка — ESX создаёт своп-файл целиком, а не по мере использования. Внутри он почти всегда пустой: реальная запись в него идёт только при host-level swapping, то есть когда хосту уже плохо с памятью. Поэтому мониторинг «фактически занято на LUN» может показывать смешные 4 % утилизации, а датастор при этом будет забит под завязку резервированием под свопы. Не путайте эти две метрики, иначе будете долго спорить с СХД. Похожая путаница бывает и в Linux, когда на ext4 свободны гигабайты, а файл не создаётся: метрика «сколько записано» и метрика «сколько можно выделить» живут отдельно.

Первое, что делаю при такой ошибке: сравниваю свободное место на датасторе с configured memory виртуалки. В восьми случаях из десяти этого достаточно, чтобы закрыть вопрос за две минуты.
Цифры и версии: Почему ВМ не включается после добавления памяти — схема
Цифры и версии: Почему ВМ не включается после добавления памяти. Открыть схему в полном размере

Какие своп-файлы ESX 9 создаёт при включении ВМ

Файлов подкачки на самом деле несколько, и путать их не надо. Первый — основной .vswp, он же «тот самый». Имя вида vmname-abcd1234.vswp, размер строго равен configured memory минус memory reservation. Резервирование 0 — файл размером во всю память ВМ. Резервирование равно всей памяти — файл не создаётся вовсе. Всё, что между, даёт файл пропорционального размера: у 64-гигабайтной машины с резервированием 32 ГБ своп будет 32 ГБ.

Второй файл — VMX swap, он выглядит как vmx-vmname-<id>.vswp и обслуживает служебную память процесса VMX (стеки потоков, код, куча — то, что нужно, чтобы поднять и обслуживать гостя). Документация по производительности vSphere говорит, что объём требуемого места варьируется, но даже для крупной ВМ обычно составляет менее 100 МБ, и менее 300 МБ, если у ВМ включена 3D-графика. Создаётся он автоматически при включении, по умолчанию — в каталоге ВМ; перенести можно параметром sched.swap.vmxSwapDir, а полностью отключить — sched.swap.vmxSwapEnabled = FALSE. Отключать я не советую: документация прямо предупреждает, что цена — существенный рост резервирования overhead-памяти хоста. Экономия в сотню мегабайт того не стоит.

Третий файл к конкретной ВМ отношения не имеет — это системный своп самого хоста, который позволяет вытеснить до 1 ГБ системной памяти гипервизора под давлением. Он настраивается отдельно через esxcli sched swap system (или в vSphere Client: хост → Configure → System Swap), и для него можно указать датастор или host cache. Ключи ниже полные — короткие варианты тоже есть, но в скриптах я пишу длинные, так читаемее:

# системный своп хоста на выбранном датасторе
esxcli sched swap system set --datastore-enabled true --datastore-name DS_INFRA_01
esxcli sched swap system get

# что реально лежит в каталоге ВМ
ls -lh /vmfs/volumes/DS_1C_01/SRV-1C/*.vswp
# SRV-1C-1f3a9c02.vswp            64.0G
# vmx-SRV-1C-2839471263-1.vswp    89.0M

И отдельно проговорю пункт, на котором спотыкаются чаще всего: SSD host cache (swap to host cache) не отменяет создание обычных своп-файлов. Формулировка в Performance Best Practices недвусмысленная — даже если перегруженный по памяти хост использует swap to host cache, ему всё равно нужно создавать обычные своп-файлы. Host cache лишь делает менее важной скорость хранилища, на котором эти файлы лежат. Это ускорение, а не замена. Я несколько раз видел, как админ включал host cache на локальном NVMe и искренне ждал, что .vswp на общем LUN исчезнут.

Мелочь, которая экономит время в переписке: с версии 9.0 гипервизор в документации Broadcom называется ESX, без «i». Это не опечатка и не статья 2008 года — вернули историческое имя.
Добавили памяти виртуалке — она перестала включаться: сколько места на datastore съедает .vswp — схема
Схема к статье. Открыть схему в полном размере
Схема своп-файлов ESX 9: .vswp равен памяти минус резервирование, VMX swap и системный своп хоста
Основной объём даёт один файл — .vswp, и его размер вы задаёте ползунком памяти.

Кейс: +40 ГБ памяти и почти три часа лишнего простоя

Условный клиент — сумочное производство «СумкаПром», 48 рабочих мест: офис, раскройный цех и склад. Инфраструктура компактная: два хоста ESX 9.0 по 192 ГБ RAM, общая СХД, кластер с HA и admission control по проценту ресурсов (50 %, то есть под резервирования реально доступна ёмкость одного хоста). Под продуктивный контур — VMFS-датастор DS_1C_01 на 2 ТБ: сервер 1С (24 ГБ RAM, диск 300 ГБ), SQL Server (64 ГБ, полное резервирование, диски 900 ГБ), терминальный сервер на 30 пользователей (64 ГБ, тоже с полным резервированием) и три служебные ВМ. Свободного места перед работами — 96 ГБ, по внутреннему регламенту «примерно ок».

В субботнее окно делали две вещи сразу: обновляли конфигурацию 1С и увеличивали память серверу 1С с 24 до 64 ГБ. Обновление прошло, ВМ выключили, поменяли память, нажали Power On — отказ. Сорок минут ушло на проверку «а не сломался ли VMDK»: смотрели vmkfstools, целостность каталога, консистентность дисков. Диски были в порядке. Считать надо было не диски, а арифметику: своп теперь требовал 64 ГБ вместо 24, а свободных к моменту включения оставалось 25 ГБ. За неделю до этого агент резервного копирования оставил на датасторе два зависших дельта-файла снапшотов на 71 ГБ, и никто их не заметил: алерт стоял на пороге 10 %.

Первое лечение было быстрым и, как это часто бывает, породило вторую проблему. Админ выставил серверу 1С резервирование на все 64 ГБ (Reserve all guest memory). Своп-файл не создаётся, ВМ включилась. А через час, когда после обновления перезагружали терминальный сервер, он включаться отказался: HA admission control посчитал, что резервирования SQL, 1С и терминала (64 + 64 + 64 ГБ) плюс overhead уже не помещаются в отведённую под них половину кластера. Сотрудники смены остались без терминала ещё на полтора часа — уже по совершенно другой причине, чем начиналось. Всего окно растянулось почти на три часа сверх плана.

Как закончили. Удалили зависшие дельты через консолидацию снапшотов — вернулся 71 ГБ. Резервирование серверу 1С снизили до 32 ГБ: это с запасом покрывает его активный рабочий набор, своп стал 32 ГБ вместо 64, а admission control снова пустил терминал. Своп-файлы продуктивных ВМ вынесли на отдельный общий датастор DS_SWAP_01 на 500 ГБ — так рост RAM больше не конкурирует за место с дисками баз. Порог алерта по свободному месту подняли с 10 до 20 % и добавили отдельную проверку «свободно на датасторе не меньше суммы незарезервированной памяти выключенных ВМ». За следующие полгода сюрпризов с включением не было.

Вывод из этого случая: увеличение памяти ВМ — операция, затрагивающая хранилище. Планируйте её как изменение дисковой ёмкости, а не как «подвинуть ползунок».
Цифры и версии: Кейс: +40 ГБ памяти и почти три часа лишнего простоя — схема
Цифры и версии: Кейс: +40 ГБ памяти и почти три часа лишнего простоя. Открыть схему в полном размере
Цифры кейса: после добавления памяти 1С .vswp требовал 64 ГБ при 25 ГБ свободных на datastore
Место съели не новые данные, а забытые дельты бэкапа — своп лишь сделал это видимым.

Как посчитать запас места на datastore заранее

Формула, которую я держу в голове перед любым изменением памяти: свободного места на датасторе должно остаться не меньше, чем (новая configured memory − резервирование) + 0,3 ГБ на VMX swap + нормальный запас на рост тонких дисков и снапшоты. Если у вас на датасторе живут выключенные ВМ, которые кто-то может включить, — их суммарная неарезервированная память тоже должна быть в запасе, иначе вы просто передвинете отказ на другую машину.

Смотреть свободное место я предпочитаю прямо на хосте, а не в GUI: цифра в vSphere Client обновляется с задержкой и в момент разбора инцидента врёт.

# свободное место по датасторам глазами хоста
esxcli storage filesystem list
df -h /vmfs/volumes/DS_1C_01

# кто и сколько держит свопом прямо сейчас
find /vmfs/volumes/DS_1C_01 -name '*.vswp' -exec ls -lh {} \;

# список ВМ и их состояние
vim-cmd vmsvc/getallvms
vim-cmd vmsvc/power.getstate <vmid>

Для планирования по всему кластеру удобнее PowerCLI. Этот отчёт показывает, сколько места под своп потребует каждая включённая ВМ, и сразу вскрывает машины с нулевым резервированием и жирной памятью:

Get-VM | Where-Object { $_.PowerState -eq 'PoweredOn' } |
  Select-Object Name,
    @{N='MemGB'; E={ $_.MemoryGB }},
    @{N='ResGB'; E={ (Get-VMResourceConfiguration $_).MemReservationGB }},
    @{N='VswpGB'; E={ $_.MemoryGB - (Get-VMResourceConfiguration $_).MemReservationGB }},
    @{N='Datastore'; E={ ($_ | Get-Datastore).Name -join ',' }} |
  Sort-Object VswpGB -Descending | Format-Table -AutoSize

Одна оговорка честности ради: имя свойства резервирования в PowerCLI зависит от версии модуля — в актуальных сборках есть MemReservationGB, в более старых приходится брать MemReservationMB и делить на 1024. Проверьте на своём окружении через Get-VMResourceConfiguration | Get-Member, прежде чем гнать отчёт по всему кластеру.

Перед изменением памяти проверяю датастор не на «сколько занято», а на «сколько освободится и займётся при следующем включении». Это разные числа, и вторая колонка обычно нигде не считается.

Резервирование памяти: когда ставить и чем оно опасно

Резервирование действительно решает исходную проблему. Поставили резервирование, равное всей памяти ВМ, — своп-файл не создаётся, требование к месту на датасторе под него падает до нуля. Плюс это гарантированно убирает host-level swapping для этой машины, а он для 1С и SQL смертельно вреден: зарезервированную память хост не отбирает ни балуном, ни своим свопом, даже если гость её сейчас не использует.

Побочка серьёзная. Хост не включит ВМ, если не может гарантировать её резервирование из незарезервированной памяти. В кластере с HA добавляется admission control: при политике по проценту ресурсов он суммирует резервирования и overhead всех включённых ВМ и сравнивает с ёмкостью, оставшейся после отложенной под отказ доли. При политике слотов ещё хуже — размер слота по умолчанию определяется самым большим резервированием, и одна ВМ с полным локом памяти резко снижает число допустимых машин. Раздали резервирования щедро — получили кластер, где ВМ перестают стартовать при формально свободной памяти.

Мой рабочий компромисс для типичного офисного контура до 50 рабочих мест: полное резервирование ставлю только там, где хост-своп недопустим по природе задачи — сервер СУБД, сервер 1С, иногда телефония. Для остальных резервирую не более половины памяти или не резервирую вовсе, а место под свопы просто закладываю в ёмкость датастора. Ставить «Reserve all guest memory» веером на все ВМ «чтобы не думать про место» — плохая идея: вы меняете понятную проблему нехватки дискового места на непонятную проблему отказов включения по памяти.

И ещё нюанс, который экономит нервы при отладке: если вы поменяли резервирование у работающей машины, эффект проявляется постепенно, а полностью — только после power-cycle. Своп-файл создаётся в момент включения, и его размер на лету не пересчитывается. Поменяли резервирование — перезагрузка ВМ обязательна, иначе на датасторе так и будет лежать старый файл прежнего размера.

Не ставьте резервирование как автоматическую реакцию на «кончилось место». Сначала посчитайте, сколько памяти в кластере вы этим забираете у остальных — иногда дешевле добавить 500 ГБ на датастор.

Где размещать своп-файлы: отдельный датастор, SSD, thin

По умолчанию своп ложится в тот же каталог, где лежит конфигурационный файл ВМ (.vmx). Это удобно, но именно из-за этого рост памяти начинает конкурировать за место с файлами баз данных на том же LUN. Поменять место можно на уровне кластера (своп в каталоге ВМ или на датасторе, заданном хостом), на уровне хоста (указать ему swap-датастор) и у конкретной ВМ в её параметрах. Для площадок, где память крутят регулярно, я выношу свопы на отдельный общий датастор — так изменение RAM перестаёт быть операцией с продуктивным хранилищем.

Локальный SSD под свопы выглядит соблазнительно и по производительности действительно хорош, но у него есть прямо задокументированная плата: размещение своп-файлов на локальном хранилище хоста может немного снизить производительность vMotion, потому что вытесненные в локальный своп страницы приходится передавать по сети на хост назначения. Для кластера с активным DRS я на это не иду. Если очень хочется выжать SSD — правильный путь другой: swap to host cache на локальном SSD, при том что обычные своп-файлы остаются на общем хранилище. Так рекомендует и сама документация: под весь объём свопа SSD обычно всё равно не хватает.

Отдельно — про тонкое размещение. Документация по управлению ресурсами vSphere говорит прямо: не храните своп-файлы на thin-provisioned LUN — рост свопа может упереться в исчерпание места на переподписанной СХД, и работающая ВМ будет остановлена. Логика понятная: своп — как раз тот файл, который обязан быть гарантированно доступен целиком. Ещё один источник «пропавшего» места — осиротевшие .vswp после аварии хоста: если хост упал с работающими ВМ, их своп-файлы остаются и занимают гигабайты, пока их не удалят.

Спорный момент, где я честно скажу «проверяйте на своей версии»: поведение свопа на vSAN. Там своп — не файл в каталоге, а отдельный объект со своей политикой хранения, и вопрос тонкий/толстый и учёт FTT менялись от версии к версии. Считать ёмкость на vSAN по формуле «память минус резервирование» напрямую нельзя — надо смотреть, какая политика применяется к swap-объектам в вашей конкретной сборке. На классическом VMFS всё предсказуемо, там формула работает буквально.

Крупный своп ещё и замедляет старт: документация отмечает, что при создании очень большого своп-файла (например, больше 100 ГБ) время включения ВМ может заметно вырасти. Для машин с сотнями гигабайт памяти это отдельный аргумент за резервирование.

Чек-лист перед изменением памяти виртуалки

Порядок действий у меня простой и занимает минут пять — против почти трёх лишних часов в разборе выше. Сначала считаем требуемое место, потом чистим мусор, потом меняем память, и только потом думаем про резервирование. Обратный порядок («сначала поставим резервирование, потом разберёмся») как раз и приводит к каскаду отказов включения.

Что делать в первую очередь, а на что можно забить. В первую очередь — свободное место на датасторе и зависшие снапшоты бэкапа: это две причины из трёх. Во вторую — размещение свопов, если вы вообще регулярно меняете память. А вот на VMX swap с его сотней мегабайт можно спокойно забить: он влияет на расчёт только у сотен ВМ на одном датасторе, и трогать sched.swap.vmxSwapEnabled я не рекомендую вообще никому. Системный своп хоста на 1 ГБ — тоже приятная мелочь, а не решение проблемы ёмкости.

И последнее, про мониторинг. Порог свободного места на продуктивном датасторе в 10 % — это порог, который сработает уже после того, как у вас перестанут включаться машины. Я ставлю 20 % и отдельно — синтетическую проверку «свободного места хватит, чтобы включить все выключенные ВМ этого датастора». Вторая проверка нестандартная, её приходится дописывать руками в Zabbix или скриптом на PowerCLI, но именно она ловит проблему до инцидента, а не после. Если вы как раз планируете уходить с VMware, логика расчёта свопа пригодится и на новой платформе — об этом я рассказывал в кейсе замены VMware на zVirt: у других гипервизоров механика другая, но вопрос «где и сколько места под подкачку» никуда не девается.

Если ВМ уже не включается и окна нет — самое быстрое лечение не резервирование, а временно вернуть прежний объём памяти. Машина стартует со старым свопом, сервис поднимется, а место вы найдёте спокойно.
Порядок действий: Чек-лист перед изменением памяти виртуалки — схема
Порядок действий: Чек-лист перед изменением памяти виртуалки. Открыть схему в полном размере
Чек-лист перед увеличением памяти виртуальной машины в ESX 9: расчёт .vswp, снапшоты, admission control
Пять минут расчёта перед окном дешевле, чем час поиска «сломанного» VMDK.

Частые вопросы

Сколько именно места на datastore нужно под .vswp?

Ровно столько, сколько составляет разница между сконфигурированной памятью ВМ и её резервированием памяти. При нулевом резервировании — весь объём RAM машины: 96 ГБ памяти означают 96 ГБ на датасторе. Плюс небольшой VMX swap, обычно менее 100 МБ (до ~300 МБ при включённой 3D-графике).

Почему проблема вылезла именно после выключения ВМ, а до этого всё работало?

Своп-файл существует только пока ВМ включена. На выключении он удаляется, место возвращается на датастор и его успевают занять соседи — тонкие диски, снапшоты бэкапа, другие ВМ. При включении машина просит уже новый, больший объём, и его не находит.

Поможет ли SSD host cache избавиться от .vswp?

Нет. Документация vSphere 9.0 прямо говорит, что даже хост со swap to host cache всё равно создаёт обычные своп-файлы. Host cache снижает влияние медленного хранилища на host-level swapping, но требование к месту на датасторе не убирает.

Можно ли просто выставить всем ВМ полное резервирование памяти и забыть про свопы?

Технически да, своп-файлы тогда не создаются. Но хост не включит ВМ, если не может гарантировать её резервирование, а HA admission control учитывает все резервирования. Веерное резервирование меняет нехватку места на отказы включения по памяти.

Я поменял резервирование у работающей ВМ, а размер .vswp не изменился. Это баг?

Нет. Своп-файл создаётся в момент включения ВМ, и его размер на лету не пересчитывается. Чтобы файл пересоздался с новым размером, машину нужно выключить и включить.

Куда лучше вынести своп-файлы?

Для кластеров, где память меняют регулярно, — на отдельный общий датастор. Локальный своп хоста быстрее, но немного замедляет vMotion. На thin-provisioned LUN своп класть нельзя.

Столкнулись с похожей задачей? Обращайтесь — решим

Если у вас происходит что-то из описанного в этой статье — или любая другая проблема с ИТ-инфраструктурой, — обращайтесь в любое время. Мои специалисты и я лично разберём ситуацию, найдём настоящую причину и доведём до решения.

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 💬 MAX: +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи