如何压缩VirtualBox的VDI文件大小?
我有一个VirtualBox虚拟机,配置了一个非常大的硬盘大小(比主机大)。
现在我已经删除了日志文件,但在使用了VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compact
之后,VDI文件的大小并没有变小,有什么方法可以真正压缩VDI文件的大小吗?谢谢!
我有一个VirtualBox虚拟机,配置了一个非常大的硬盘大小(比主机大)。
现在我已经删除了日志文件,但在使用了VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compact
之后,VDI文件的大小并没有变小,有什么方法可以真正压缩VDI文件的大小吗?谢谢!
你必须执行以下步骤:
清除空闲空间:
关闭来宾 VM
现在,运行 VBoxManage 的 modifymedium
命令,并使用 --compact
选项:
这样可以减少 vdi 的大小。
我在一个Windows 7主机上使用的是Windows客机,这里是我写的一个批处理文件,将所有的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
我在评论中留下了链接,这样你就可以(有点)告诉你它是如何工作的。
这不是一个直接的答案,因为我是在解决这个问题,而不是问题。这个解决方案不是定期压缩映像,而是使用 discard 自动删除主机上的虚拟机磁盘映像中未使用的块。Arch Linux wiki 有一个支持 TRIM 操作的文件系统列表。
FDE 和 cryptoroot 特别不包括在其中,因为有安全问题,而且这个问题的其他解决方案都不允许压缩。在Arch Linux wiki上有关于TRIM和dm-crypt设备的信息。
从理论上讲,这对使用VDI存储的VMX主机上的所有Linux客人都可以工作。这个时候,discard
不在GUI中,但nonrotational
作为 “固态硬盘 "复选框显示出来了。(参考: vbox论坛,discard support )
<AttachedDevice discard="true" nonrotational="true" type="HardDisk" [..other options..] >
sudo hdparm -I /dev/sda | grep TRIM
启动虚拟机,验证是否启用了TRIM支持:
devices {
...
issue_discards = 1
}
如果使用LVM,更改discard
中的discard设置。(Ref: debian wiki, lvm.conf example )
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
在 fstab 中,将 nonrotational
选项添加到你希望自动丢弃的文件系统中 (Ref: debian wiki, fstab example )
sudo mount -o remount /
sudo mount -o remount /build
重装文件系统,让它们重新获得新的选项。
fstrim /
fstrim /build
现在用/etc/lvm/lvm.conf
手动修剪自由块。不要在discard
中设置连续丢弃,可以在每周的cron中进行。(每周一次的 cron 建议用于物理固态硬盘,因为它们可能对 TRIM 的支持有问题,但这与此无关,因为底层固态硬盘由主机操作系统处理。
&001
此时,虚拟机内的文件系统的大小和虚拟机映像的大小应该很接近。Debian 8.7, 内核:linux 4.8 grsec from backports, 文件系统:ext4 - Guest2: Debian 9 RC2, 内核:linux 4.9, 文件系统:ext4 - Host1: VBox 5.1.14, Win7, image fmt: VDI - Host2: 主机2: VBox 5.1.14, Win8.1, image fmt: VDI
我在Windows VirtualBox中的虚拟Debian上挂载的VDI镜像中使用了这个。这不是一个通用的解决方案,但至少可以让你了解我的做法。
Debian中的命令:*
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
Windows中的命令:
C:\Program Files\Oracle\VirtualBox>VBoxManage.exe modifyhd --compact "D:\VirtualBox VMs\web.vdi" # convert zeros to empty space
希望对你有帮助 :)
我不想在OS中启用TRIM支持,因为每次删除数据都会强制压缩VDI文件中的数据,当VDI文件在经典旋转盘上时,会导致访客系统无法使用。对我来说,最好的办法是手工压缩,例如每月一次。
在正常的压缩过程中,VDI文件内容会被复制到新的文件中。
我有一个类似于Andrew Domaszek指出的解决方案。要做到这一点:
创建新的虚拟机,用GParted Live CD启动(你可以使用你喜欢的Linux发行版)。
编辑机器设置并设置 SATA 磁盘控制器
添加您想要压缩的现有的 VDI 文件
更改基于 VDI 的磁盘,使其成为支持 TRIM 的固态硬盘:
启动机器
在 Linux 根目录下,挂载 NTFS 分区 mount /dev/sda2 /mnt
零可用空间 dd if=/dev/zero of=/mnt/bigfile
强制压缩 VDI 而不创建新文件: rm /mnt/bigfile
LEGACY (~1997-2007) 操作系统的重要注意
一般来说,前面给出的答案中的技巧都是有效的;但是,有一个非常重要的特殊情况。因此,当试图通过写入一个0的文件来消耗所有的空闲空间时(这应该总是以root的身份进行,以包括root的特权空闲空间,其他人无法触碰),你可能会看到:
文件太大了
,而不是你所期望的:
设备上没有空间了。这在当时是很常见的,因为许多文件操作都是以32位整数的形式返回结果,所以负值会报告错误代码。
如果你是一个讲师,想在课堂上演示这种情况,那么用一个4GB的磁盘映像和Red Hat Linux 7.0的旧版本就足够了。