Как уменьшить размер файла VDI VirtualBox?


302

У меня есть виртуальная машина VirtualBox, в которой настроен очень большой размер жесткого диска (больше, чем у хоста). По моей ошибке программа на виртуальной машине генерировала множество файлов журналов, и размер файла VDI продолжает расти до тех пор, пока на хосте не останется свободного места.

Теперь я удалил файлы журналов, но размер файла VDI не уменьшается после использования VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compact

Есть ли способ действительно сжать размер файла VDI? Спасибо!

Ответы:


508

Вы должны сделать следующие шаги:

  1. Запустите дефрагментацию в гостевой системе (только для Windows)
  2. Обнулить свободное пространство:

    С гостем Linux запустите это:

    dd if=/dev/zero of=/var/tmp/bigemptyfile bs=4096k ; rm /var/tmp/bigemptyfile
    

    Или же:

    telinit 1
    mount -o remount,ro /dev/sda1
    zerofree -v /dev/sda1
    

    С гостем Windows загрузите SDelete от Sysinternals и запустите это:

    sdelete.exe c: -z
    

    (замените C: буквой диска VDI)

  3. Отключение гостевой ВМ

  4. Теперь запустите modifymediumкоманду VBoxManage с --compactпараметром:

    С хостом Linux запустите это:

    vboxmanage modifymedium --compact /path/to/thedisk.vdi
    

    С хостом Windows запустите это:

    VBoxManage.exe modifymedium --compact c:\path\to\thedisk.vdi
    

    С хостом Mac запустите это:

    VBoxManage modifymedium --compact /path/to/thedisk.vdi
    

Это уменьшает размер VDI.


16
Для следующего человека моя команда в конечном итоге выглядела так: "C: \ Program Files \ Oracle \ VirtualBox \ VBoxManage.exe" modifyhd "C: \ Users \ daniel \ VirtualBox VMs \ .... \ thedisk.vdi" - -компакт
Даниил

36
Согласно справочной странице утилиты Linux zerofree ( manpages.ubuntu.com/manpages/natty/man8/zerofree.8.html ), для этой работы zerofree должен быть лучше, чем dd . dd не был бы рекомендован, потому что «он медленный», «он заставляет образ диска (временно) увеличиваться до максимальной степени», «он (временно) использует все свободное место на диске, поэтому другие одновременные действия записи могут завершиться с ошибкой». Zerofree доступен в Ubuntu Linux через apt , или вы можете скомпилировать его самостоятельно.
Дакатин

27
Забавно, что на man- странице zerofree говорится, что с dd другие параллельные записи завершатся неудачно, но zerofree требует, чтобы файловая система была смонтирована только для чтения! * Дух *
Мадарко

7
Подсказка. Поместите две команды в одну строку следующим образом: dd ...; rm /bigfileэто сведет к минимуму время с полным диском, если вы не ожидаете ddзавершения.
JLH

21
@Dakatine При использовании VirtualBox 4.3.10 файл образа диска не увеличился в максимальном размере. VirtualBox достаточно умен, чтобы не беспокоить запись всех нулевых блоков на физический диск.
JLH

12

Я на хосте Windows 7 с гостями Windows. Вот пакетный файл, который я записал в Compact все VDI в дереве папок.

echo off
mode con:cols=140 lines=200
cls
:: see https://forums.virtualbox.org/viewtopic.php?p=29272#p29272
:: How can I reduce the size of a dynamic VDI on disk?
:: but that page says to use sdelete -s which is suboptimal. 
:: use -z as per http://technet.microsoft.com/en-us/sysinternals/bb897443.aspx

:: First run the sdelete -z c: inside the VMs that zero-out all the free space
:: THEN run this batch file 

Title Compacting Free space on Virtual Machine VMs

:: http://ss64.com/nt/for_r.html
:: http://stackoverflow.com/questions/8836368/windows-batch-file-how-to-loop-through-files-in-a-directory/8836401#8836401

Setlocal EnableDelayedExpansion
:: http://ss64.com/nt/delayedexpansion.html ... 
:: Notice that within the for loop we use !variable! instead of %variable%.

For /R %CD% %%G IN (*.vdi) DO (
 set ohai=%%G
 set lastfive=!ohai:~-5!
:: Skip snapshots which are named {guid}.vdi
 if NOT !lastfive!==}.vdi (
 echo .
 echo Compacting %%G
 "C:\Program Files\Oracle\VirtualBox\VboxManage.exe" modifyhd "%%G" --compact )
 )

pause 
exit

Я оставил ссылки в комментариях, чтобы вы могли (вроде) рассказать, как это работает.

редактировать

Что ж, после всего этого я попробовал инструмент CloneVDI, и он отлично справился с задачей за гораздо меньшее время и одним щелчком мыши.


5
Вы могли бы подумать, что на таком сайте будет какая-то подсветка синтаксиса для DOS, но нет. В Notepad ++ это выглядит намного симпатичнее
CAD

1
@CAD_bloke, для которого потребуется механизм синтаксического анализа, и когда вы рассматриваете количество различных языков, опубликованных на SE, вы смотрите на ОГРОМНЫЙ проект. Подумайте, например, сколько версий и диалектов DOS существует, и это еще до того, как вы
перейдете

Очень хороший момент. Как ни странно это будет выделено на обменном стека IOS приложение.
САПР bloke

2
Да, CloneVDI - намного лучший и более быстрый способ для личного использования
VarunAgw

6

Гость Debian на хосте Windows с использованием discard / TRIM.

Это не прямой ответ сам по себе, так как я решаю проблему, а не вопрос. Вместо того, чтобы периодически сжимать образ, это решение использует Discard для автоматического удаления неиспользуемых блоков в образе диска виртуальной машины.

Это решение требует гостевой файловой системы, которая поддерживает непрерывную TRIM. Вики Linux Arch содержит список файловых систем, поддерживающих операции TRIM .

FDE и cryptoroot конкретно не рассматриваются, так как существуют проблемы безопасности, и ни одно из других решений этого вопроса также не позволит сжать. Вики Linux Arch содержит информацию об устройствах TRIM и dm-crypt .

Теоретически, это будет работать для всех гостей Linux на хостах VBox, использующих хранилище VDI.

Конфигурация хоста

Когда VBox завершен, а виртуальные машины не запущены, добавьте поддержку Discard на свои диски, указав оба discardи nonrotationalкаждый диск в файле конфигурации для VM. В настоящее время discardотсутствует в графическом интерфейсе, но nonrotationalотображается как флажок «Твердотельный накопитель». (ссылка: форумы vbox, поддержка отмены )

<AttachedDevice discard="true" nonrotational="true" type="HardDisk" [..other options..] >

Загрузите виртуальную машину и убедитесь, что включена поддержка TRIM:

sudo hdparm -I /dev/sda | grep TRIM

Гостевая конфигурация

Если LVM используется, измените настройку сброса в /etc/lvm/lvm.conf. (ссылка: Debian Wiki, пример lvm.conf )

devices {
...
    issue_discards = 1
}

В fstab добавьте discardопцию к файловым системам, которые вы хотите автоматически отбрасывать (ref: debian wiki, пример fstab )

UUID=8db6787f-1e82-42d8-b39f-8b7491a0523c   /   ext4    discard,errors=remount-ro   0   1
UUID=70bfca92-8454-4777-9d87-a7face32b7e7   /build  ext4    discard,errors=remount-ro,noatime   0   1

Перемонтируйте файловые системы, чтобы они выбрали новые опции.

sudo mount -o remount /
sudo mount -o remount /build

Вручную обрезать свободные блоки теперь с fstrim. fstrimиспользует смонтированную файловую систему, а не блочное устройство, поддерживающее ее. Вместо установки непрерывного сброса fstabэто можно сделать в еженедельном кроне. (Еженедельный cron рекомендуется для физических твердотельных накопителей, которые могут иметь сомнительную поддержку TRIM, но здесь это не актуально, поскольку базовые твердотельные накопители обрабатываются операционной системой хоста. См .: предупреждение об ssd trim ).

fstrim /
fstrim /build

На этом этапе размер файловых систем внутри ВМ и размер образов ВМ должны быть довольно близки по значению.

Протестировано с:

  • Гость1: Debian 8.7, ядро: linux 4.8 grsec от backports, файловая система: ext4
  • Гость 2: Debian 9 RC2, ядро: linux 4.9, файловая система: ext4
  • Host1: VBox 5.1.14, Win7, образ fmt: VDI
  • Host2: VBox 5.1.14, Win8.1, образ fmt: VDI

2

Для гостя MacOS сделайте это:

  1. Обнулить свободное место в гостевой системе:

    diskutil secureErase freespace 0 "/Volumes/Macintosh HD"
    

    (замените / Volumes / Macintosh HD на имя вашего диска)

  2. Отключение гостевой ВМ

  3. Запустите эту команду, чтобы уменьшить размер образа диска VDI

    VBoxManage modifyhd /path/to/thedisk.vdi --compact
    

    ИЛИ ЖЕ

    VBoxManage modifymedium /path/to/thedisk.vdi --compact
    

1

Я использую это для моего образа VDI, подключенного к виртуальному Debian в Windows VirtualBox. Это не общее решение, но оно должно по крайней мере дать вам представление о том, что я делаю.

Команды в Debian:

root@debian:~# lsblk  # show partitions
НАИМЕНОВАНИЕ MAJ: MIN RM РАЗМЕР RO ТИП MOUNTPOINT 
SDB 8:16 0 128G 0 диск 
S─sdb1 8:17 0 128G 0 part / mnt / web # ЭТО РАЗДЕЛ ИНТЕРЕСА!
сда 8:00 64G 0 диск 
S─sda1 8: 1 61,4G 0 часть / 
├─sda2 8: 2 1K 0 часть 
S─sda5 8:50 2,7G 0 часть 
[SWAP] sr0 11: 0 1 56,3M 0 rom
root@debian:~# service mysql stop  # terminate all operations with partition
root@debian:~# service apache2 stop  # terminate all operations with partition
root@debian:~# umount /mnt/web  # unplug partition
root@debian:~# apt-get install zerofree  # install tool for filling in zeros to empty space
root@debian:~# zerofree -v /dev/sdb1  # fill with zeros
root@debian:~# poweroff  # shut down machine

Команды в Windows:

C:\Program Files\Oracle\VirtualBox>VBoxManage.exe modifyhd --compact "D:\VirtualBox VMs\web.vdi"  # convert zeros to empty space

Надеюсь, это поможет :)


1

Я не хочу включать поддержку TRIM в ОС, потому что каждое удаление данных вызывает сжатие данных в файле VDI, делая гостевую систему непригодной для использования, когда файл VDI находится на классическом ротационном диске. Для меня лучше выполнять сжатие вручную, например, раз в месяц.

При обычном сжатии содержимое файла VDI копируется в новый файл. Это требует некоторого (иногда большого) свободного места на диске хоста.

У меня есть решение, аналогичное указанному Эндрю Домашек. Это работает очень хорошо даже с NTFS (Windows10).

Сделать это:

  • создайте новую виртуальную машину, которая загружается с GParted Live CD (вы можете использовать ваш любимый дистрибутив Linux).
  • Отредактируйте настройки машины и установите контроллер диска SATA
  • Добавьте существующие файлы VDI, которые вы хотите сжать
  • Измените диски на основе VDI, чтобы они отображались как SSD с поддержкой TRIM:

    VBoxManage storageattach "gpared live" --storagectl "SATA" --port 0 --discard on --nonrotational on
    VBoxManage storageattach "gpared live" --storagectl "SATA" --port 1 --discard on --nonrotational on
    
  • запустить машину

  • В корневой оболочке Linux смонтируйте раздел NTFS mount /dev/sda2 /mnt
  • ноль свободного места dd if=/dev/zero of=/mnt/bigfile
  • rm /mnt/bigfile
  • принудительное сжатие VDI без создания нового файла: fstrim -v /mnt

0

Очень приятный трюк в дополнение к принятому ответу заключается в том, что вы можете обойтись без какого-либо уплотнения после обнуления гостевого пространства, используя сжатую файловую систему на хосте (например, выбрав сжатие папки виртуальных дисков в свойствах NTFS на Хост Windows). На самом деле это дает преимущество, позволяющее сэкономить гораздо больше места, поскольку операционные системы, как правило, содержат много повторяющихся текстовых или двоичных файлов (например, гостевой диск объемом 30 ГБ с обнуленным 15 ГБ пространства может превратиться в 4 ГБ на главном диске).

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


0

ВАЖНОЕ ПРИМЕЧАНИЕ ДЛЯ LEGACY (~ 1997-2007) ОПЕРАЦИОННЫЕ СИСТЕМЫ

В целом, методы в приведенных ранее ответах являются действительными; ОДНАКО, есть очень важный особый случай.

В течение нескольких лет - возможно, 1997-2007 гг. Или около того - 32-разрядные операционные системы оставались нормой, но жесткие диски объемом более 2 ГБ уже использовались. В результате, при попытке использовать все свободное пространство путем записи файла нулей (который всегда должен выполняться как root, чтобы включить привилегированное свободное пространство root, которое никто больше не может коснуться), вы можете увидеть:

Файл слишком большой

вместо того, что вы ожидаете:

На устройстве нет свободного места.

В этом случае вы, скорее всего, столкнулись с ограничением размера файла 2 ГБ. В то время это было распространено, потому что многие файловые операции возвращали результаты в виде 32-разрядных целых чисел со знаком, так что отрицательные значения могли сообщать коды ошибок. Это фактически означало, что результаты смещения были ограничены 2 ^ 31 байтами без специальных мер.

Обходной путь прост: продолжайте создавать отдельные файлы обнуления с разными именами до тех пор, пока на диске фактически не останется свободного места.

Если вы являетесь инструктором, желающим продемонстрировать эту ситуацию для класса, достаточно образа диска объемом 4 ГБ со старой копией Red Hat Linux 7.0.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.