Jak skompaktować rozmiar pliku VDI VirtualBox?


284

Mam VirtualBox VM, który skonfigurował bardzo duży rozmiar dysku twardego (większy niż host). Przez mój błąd program na maszynie wirtualnej wygenerował wiele plików dziennika, a rozmiar pliku VDI rośnie, dopóki nie ma miejsca na hoście.

Teraz usunąłem pliki dziennika, ale rozmiar pliku VDI nie zmniejsza się po użyciu VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compact

Czy istnieje sposób, aby naprawdę zmniejszyć rozmiar pliku VDI? Dzięki!

Odpowiedzi:


481

Musisz wykonać następujące czynności:

  1. Uruchom defrag w gościu (tylko Windows)
  2. Pusta wolna przestrzeń:

    Z Gość Linux Uruchom to:

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

    Lub:

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

    Z Gość Windows , Ściągnij SDelete z Sysinternals i uruchom to:

    sdelete.exe c: -z
    

    (zastąp C: literą dysku VDI)

  3. Zamknij maszynę wirtualną gościa

  4. Teraz uruchom VBoxManage modifymedium polecenie z --compact opcja:

    Z Host Linuksa Uruchom to:

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

    Z Host systemu Windows Uruchom to:

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

    Z Host Mac Uruchom to:

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

Zmniejsza to rozmiar vdi.


13
Dla następnej osoby moje polecenie wyglądało tak: "C: Program Files Oracle VirtualBox VBoxManage.exe" modifyhd "C: Daniel Daniel VirtualBox VMs ... dysk.vdi" - -kompaktowy
Daniel

36
Zgodnie z podręcznikiem zerofree dla Linuksa ( manpages.ubuntu.com/manpages/natty/man8/zerofree.8.html ), zerofree powinien być lepszy niż dd dla tej pracy. dd nie byłby zalecany, ponieważ „jest powolny”, „sprawia, że ​​obraz dysku (tymczasowo) rośnie do maksymalnego zakresu”, „tymczasowo” wykorzystuje całe wolne miejsce na dysku, więc inne współbieżne operacje zapisu mogą się nie powieść ”. Zerofree jest dostępny na Ubuntu Linux via trafny lub możesz sam go skompilować.
Dakatine

23
To zabawne, że strona podręcznika zerofree stwierdza to z dd inne współbieżne zapisy nie powiodą się, ale zerofree potrzebuje systemu plików do zamontowania tylko do odczytu! * duh *
Madarco

7
Wskazówka: umieść dwa polecenia w jednym wierszu w ten sposób: dd ...; rm /bigfile, to zminimalizuje czas z pełnym dyskiem w przypadku, gdy nie będziesz czekać na dd ukończyć.
jlh

19
@Dakatine Używając VirtualBox 4.3.10, zrobił to plik obrazu dysku nie rosnąć w maksymalnym stopniu. VirtualBox jest na tyle sprytny, że nie przeszkadza w zapisywaniu wszystkich zerowych bloków na dysku fizycznym.
jlh

36

Jeśli uruchomienie polecenia w zaakceptowanej odpowiedzi spowoduje powstanie niepomyślnego komunikatu o błędzie takiego jak ten

VBoxManage.exe: error: Cannot register the hard disk 'thedisk.vdi'
{aaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeee} because a hard disk 'thedisk.vdi'
with UUID {aaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeee} already exists

Po prostu uruchom polecenie przez identyfikator UUID zamiast nazwy pliku:

VBoxManage.exe modifyhd {aaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeee} --compact

11

Jestem na komputerze z systemem Windows 7 z gośćmi w systemie Windows. Oto plik wsadowy, który napisałem do Kompaktuj wszystkie VDI w drzewie folderów

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

Pozostawiłem linki w komentarzach, abyś mógł (w pewnym sensie) powiedzieć, jak to działa.

edytować

Po tym wszystkim spróbowałem Narzędzie CloneVDI i wykonał dobrą robotę w znacznie krótszym czasie i jednym kliknięciem.


5
Pomyślałbyś, że na tej stronie będzie jakiś podświetlanie składni dla DOS-a, ale nie. W Notepad ++ wygląda o wiele ładniej
CAD bloke

1
@CAD_bloke, który wymagałby silnika analizującego, a gdy weźmiesz pod uwagę liczbę różnych języków opublikowanych w SE, patrzysz na OGROMNY projekt. Pomyśl tylko, ile wersji i dialektów DOS-a jest na przykład, a zanim jeszcze przejdziesz do Linuksa itp.
Caltor

Bardzo dobry punkt. Jak na ironię jest podświetlone na aplikacji wymiany iOS na stosie.
CAD bloke

2
Tak CloneVDI jest znacznie lepszym i szybszym sposobem do użytku osobistego
VarunAgw

6

Gość Debiana na hoście Windows przy użyciu odrzucenia / TRIM.

Nie jest to bezpośrednia odpowiedź jako taka, ponieważ zajmuję się problemem, a nie pytaniem. Zamiast okresowego kompaktowania obrazu, to rozwiązanie wykorzystuje odrzucanie, aby automatycznie usuwać nieużywane bloki na obrazie dysku maszyny wirtualnej hosta.

To rozwiązanie wymaga systemu plików gościa obsługującego ciągły TRIM. Wiki z Arch Linux ma lista systemów plików obsługujących operacje TRIM .

FDE i kryptoroot nie są specjalnie omówione, ponieważ istnieją obawy związane z bezpieczeństwem, a żadne inne rozwiązanie tego pytania również nie pozwoliłoby na kompaktowanie. Wiki o Arch Linux ma informacje na ten temat Urządzenia TRIM i dm-crypt .

Teoretycznie będzie to działać dla wszystkich gości Linuksa na hostach VBox korzystających z pamięci VDI.

Konfiguracja hosta

Po zamknięciu VBox i braku uruchomionych maszyn wirtualnych dodaj obsługę dysków do dysków, ustawiając oba discard i nonrotational dla każdego dysku w pliku konfiguracyjnym maszyny wirtualnej. W tym czasie discard nie ma w GUI, ale nonrotational jest widoczne jako pole wyboru „Dysk SSD”. (ref: fora vbox, odrzuć wsparcie )

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

Uruchom maszynę wirtualną i sprawdź, czy obsługa TRIM jest włączona:

sudo hdparm -I /dev/sda | grep TRIM

Konfiguracja gościa

Jeśli LVM jest w użyciu, zmień ustawienie odrzucania /etc/lvm/lvm.conf. (ref: debian wiki, przykład lvm.conf )

devices {
...
    issue_discards = 1
}

W fstab dodaj discard opcja dla systemów plików, które chcesz automatycznie odrzucić (ref: debian wiki, przykład 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

Ponownie zainstaluj systemy plików, aby odebrać nowe opcje.

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

Ręcznie przycinaj teraz wolne bloki fstrim. fstrim używa zamontowanego systemu plików, a nie urządzenia blokowego, które go wspiera. Zamiast ustawiać ciągłe odrzucanie fstab, można to zrobić na cronie tygodniowym. (Cotygodniowy cron jest zalecany dla fizycznych dysków SSD, które mogą mieć wątpliwe wsparcie dla TRIM, ale nie ma to znaczenia, ponieważ podstawowe dyski SSD są obsługiwane przez system operacyjny hosta. ssd ostrzeżenie trym ).

fstrim /
fstrim /build

W tym momencie rozmiar systemów plików w maszynie wirtualnej i rozmiar obrazów maszyn wirtualnych powinny być bardzo zbliżone.

Testowane z:

  • Guest1: Debian 8.7, jądro: linux 4.8 grsec z backportów, system plików: ext4
  • Guest2: Debian 9 RC2, jądro: linux 4.9, system plików: ext4
  • Host1: VBox 5.1.14, Win7, obraz fmt: VDI
  • Host2: VBox 5.1.14, Win8.1, obraz fmt: VDI

2

Dla MacOS Guest Zrób to:

  1. Zlikwiduj wolne miejsce w systemie gościa:

    diskutil secureErase freespace 0 "/Volumes/Macintosh HD"
    

    (zastąp / Volumes / Macintosh HD nazwą napędu)

  2. Zamknij maszynę wirtualną gościa

  3. Uruchom to polecenie, aby zmniejszyć rozmiar obrazu dysku VDI

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

    LUB

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

1

Używam tego do mojego obrazu VDI zamontowanego na wirtualnym Debianie w Windows VirtualBox. To nie jest ogólne rozwiązanie, ale powinno przynajmniej dać ci wgląd w to, co robię.

Polecenia w Debianie:

root@debian:~# lsblk  # show partitions
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT 
sdb 8:16 0 128G 0 disk 
└─sdb1 8:17 0 128G 0 part /mnt/web  # THIS IS THE PARTITION OF INTEREST!
sda 8:0 0 64G 0 disk 
├─sda1 8:1 0 61,4G 0 part / 
├─sda2 8:2 0 1K 0 part 
└─sda5 8:5 0 2,7G 0 part 
[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

Polecenia w systemie Windows:

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

Mam nadzieję, że to pomoże :)


1

Nie chcę włączać obsługi TRIM w systemie operacyjnym, ponieważ każde usunięcie danych wymusi kompaktowanie danych w pliku VDI, czyniąc system gościa bezużytecznym, gdy plik VDI jest na klasycznym dysku rotacyjnym. Dla mnie lepiej jest wykonać zagęszczanie ręcznie, np. raz na miesiąc.

Podczas normalnego kompaktowania zawartość pliku VDI jest kopiowana do nowego pliku. Wymaga to (czasem dużego) wolnego miejsca na dysku hosta.

Mam rozwiązanie podobne do wskazanego przez Andrew Domaszka. Działa bardzo dobrze nawet z NTFS (Windows10).

Aby to zrobić:

  • stwórz nową maszynę wirtualną, która uruchamia się z GParted Live CD (możesz użyć ulubionej dystrybucji Linuksa).
  • Edytuj ustawienia maszyny i ustaw kontroler dysku SATA
  • Dodaj istniejące pliki VDI, które chcesz kompaktować
  • Zmień dyski oparte na VDI, aby były widoczne jako SSD z obsługą 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

  • uruchom maszynę
  • W powłoce głównej systemu Linux zamontuj partycję NTFS mount /dev/sda2 /mnt
  • zero wolnego miejsca dd if=/dev/zero of=/mnt/bigfile
  • rm /mnt/bigfile
  • wymuszenie kompaktowania VDI bez tworzenia nowego pliku: fstrim -v /mnt

0

Bardzo zgrabnym sposobem na uzupełnienie akceptowanej odpowiedzi jest to, że możesz uciec bez kompaktowania po wyzerowaniu przestrzeni gościa, używając skompresowanego systemu plików na hoście (np. Wybierając kompresowanie folderu napędów wirtualnych na właściwościach NTFS na Host systemu Windows). Ma to tę zaletę, że pozwala zaoszczędzić dużo więcej miejsca, ponieważ systemy operacyjne często przechowują wiele powtarzających się plików tekstowych lub binarnych (np. Dysk o pojemności 30 GB, który miał 15 GB miejsca zerowanego, może zmienić się na 4 GB na dysku hosta).

Ostrzeżenia obejmują fakt, że dostęp do dysku na rzeczywistym sprzęcie może wzrosnąć, a użycie procesora nieznacznie wzrasta.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.