我最初有一个大约 3.5 TiB 的单个虚拟磁盘文件 (.qcow2),出于各种原因,我决定将所有类似数据“分组”到它自己的虚拟磁盘文件上。显然,这意味着我可以缩小原始磁盘文件(至 900 GiB),但是ls
,stat
朋友们仍然列出原始的 3.5 TiB:
$ ls -lhks mydisk.qcow2
722G -rw-r--r-- 1 root root 3.5T Aug 6 18:06 mydisk.qcow2
当然,我缩小了文件系统本身(ext4)并随后稀疏了文件,这就是为什么当前只分配了 722 GiB。但我的备份工具仍然检测到 3.5 TiB,因此会扫描全部数据,而磁盘本身只能容纳 900 GiB,这意味着完成所需的时间几乎是所需时间的 4 倍。
如何“刷新”报告的尺寸?这是一台带有 HDD 的机器,所以我想文件可能太碎片化并且在 3.5 TiB 标记周围有一些东西?但是复制文件不会自动修复这个问题吗(我尝试过,至少没有)?此外,如果重要的话,磁盘文件本身也驻留在 ZFS 上。
如果可能的话任何解决方案都最好有效到位。关闭使用磁盘的虚拟机一段时间并不是问题。
答案1
看起来有几种就地执行此操作的方法:
zerofree [-v] /dev/vdXY
从内部使用客人VM(如果是 Linux,我的都是)来查找非零未分配块(“删除”的东西)并将其替换为零。跟随fallocate --dig-holes mydisk.qcow2
从主持人用孔替换零。尽管后者可能不是必需的,具体取决于主机的文件系统,但我相信如果启用压缩,ZFS 会自动将其视为稀疏。- 只需使用
virt-sparsify --in-place mydisk.qcow2
它似乎既可以进行归零又可以打孔。据我所知,这确实需要 libguestfs 中的修剪/丢弃/取消映射支持。但如果版本不是太旧,它应该在那里。
为了测试,我创建了一个 10 GiB 的磁盘,添加了一些文本文件,用其余文件填充dd if=/dev/urandom
,然后删除了最后一个文件。du -h
确认9.8G
已分配。然后我直接复制了一些虚拟磁盘并分别进行了测试:
- 由于我使用 ZFS 压缩,因此
zerofree
它已经减少到 1173 kB(1200640 字节)。fallocate
不会改变任何事情(预期)。 - 更进一步,达到 875 kB(895488 字节)。
很难判断是 ZFS 压缩还是zerofree
在这种情况下效率有点低。但这virt-sparsify
是来自主机的一个命令,而且似乎也更快,所以我就使用它。