无标题
PVE 虚拟机磁盘空间优化与自动回收指南 (qcow2)
📖 目录
1. 核心原理:为什么 df -h 显示很大但实际占用很小?
🤔 现象
在虚拟机内运行 df -h,看到磁盘总大小(Size)是 174G,已用(Used)是 61G。
用户常误以为:“我压缩了磁盘,为什么这里还是显示 174G?是不是没成功?”
💡 真相:逻辑大小 vs 物理大小
逻辑大小 (Logical Size / Size):
- 这是告诉操作系统:“你有一个 174G 的硬盘可以用”。
- 压缩不会改变这个值。如果您希望这个值变小,必须要在分区层面进行“缩小分区”操作(高风险,通常不必要)。
- 作用:保证您未来有空间写入新数据,无需频繁扩容。
物理大小 (Physical Size / Actual Usage):
- 这是 qcow2 文件在 PVE 宿主机硬盘上实际占用的空间。
- qcow2 的特性:它是“稀疏文件”(Sparse File)。它只存储实际写入的数据块。
- 效果:
- 虚拟机认为有 174G。
- 实际上只用了 61G 数据。
- 宿主机硬盘只被占用约 61G(加上少量元数据)。
- 剩下的 113G 空闲空间在宿主机上完全不占位置。
🔄 删除文件后空间会自动回来吗?
- 默认情况:不会。
- 当您在虚拟机里删除一个 10G 的文件,文件系统标记这些块为“空闲”,但 qcow2 文件仍然保留这些块的历史记录(因为不知道您以后会不会写新数据进去,或者是否只是临时删除)。
- 解决方案:需要启用 TRIM/Discard 机制,告诉底层“这些块彻底没用了,可以释放”。
2. PVE 宿主机端配置 (关键步骤)
此步骤必须在 PVE 管理界面 完成,否则虚拟机内的优化指令无法传递到底层。
🛠️ 操作步骤
- 选中虚拟机 -> 点击 **硬件 (Hardware)**。
- 双击需要优化的硬盘 (例如
scsi0或sata0)。 - 在弹出的窗口中,确保勾选/设置以下选项:
| 选项 | 推荐设置 | 说明 |
|---|---|---|
| 丢弃 (Discard) | ✅ 勾选 | 核心项。允许虚拟机发送 TRIM 指令,通知宿主机回收空闲块。 |
| IO thread | ✅ 勾选 | 提升并发 I/O 性能,避免阻塞。 |
| SSD 仿真 (SSD Emulation) | ✅ 勾选 | 如果宿主机是 SSD,勾选此项让虚拟机系统启用 SSD 优化策略。 |
| 缓存 (Cache) | 默认 (无缓存) | 最安全。除非有 UPS 且追求极致性能,否则不要选 Write Back。 |
| 异步 IO | io_uring | 现代 Linux 内核的高效 I/O 接口 (PVE 7+ 推荐)。 |
- 点击 OK 保存。
- 重要:部分设置(特别是 Discard 和 SSD 仿真)可能需要 重启虚拟机 才能生效。
3. 虚拟机内部配置 (Linux)
此步骤在 虚拟机终端 内执行。
🚀 启用自动 Trim (fstrim)
现代 Linux 发行版通常自带 fstrim.timer,但可能未启用。
检查状态:
systemctl status fstrim.timer
- 如果显示
active (waiting)或enabled,则无需操作。 - 如果显示
disabled或inactive,请继续。
- 如果显示
启用并启动定时任务:
sudo systemctl enable fstrim.timer
sudo systemctl start fstrim.timer- 作用:系统会默认每周自动运行一次
fstrim,扫描并回收空闲空间。 - 安全性:完全安全,只操作标记为“未使用”的块,不影响现有数据。
- 作用:系统会默认每周自动运行一次
**手动立即执行一次 (可选)**:
sudo fstrim -v /
- 输出示例:
/: 12.5 GiB was trimmed - 这表示有 12.5G 的空间被标记为可回收。注意:此时 qcow2 文件大小可能不会立即变小,但这为后续的快照合并或手动压缩做好了准备。
- 输出示例:
4. 验证与测试
✅ 验证 1:确认 PVE 端设置生效
在虚拟机内运行:
lsblk -D |
查看输出中的 DISC-GRAN 和 DISC-MAX 列。
- 如果有数值(如
512K或4M),且DISC-ZERO为1,说明 Discard 已生效。 - 如果全为
0B,说明 PVE 端的“丢弃”选项未勾选或未重启虚拟机。
✅ 验证 2:确认宿主机空间节省
在 PVE 宿主机 SSH 中运行:
ls -lh /var/lib/vz/images/<VMID>/vm-<VMID>-disk-0.qcow2 |
- 对比文件大小:它应该接近虚拟机内
df -h的 Used 列大小,而不是 Size 列大小。 - 对比总空间:运行
df -h /(假设您的存储池在根目录),可用空间应显著增加。
5. 自动化维护脚本 (一键压缩)
虽然 fstrim 能标记空闲块,但 qcow2 文件本身不会自动收缩(Shrink)。如果您删除了大量数据并希望 立即 看到 .qcow2 文件变小,需要运行此脚本。
⚠️ 注意事项
- 该脚本会 停止虚拟机 进行压缩,会有短暂停机时间。
- 建议每月执行一次,或在清理大量数据后执行。
📜 脚本内容 (optimize_disk.sh)
|
📝 使用方法
- 在 PVE 宿主机创建文件:
nano optimize_disk.sh - 粘贴代码,修改
VMID。 - 赋予权限:
chmod +x optimize_disk.sh - 运行:
./optimize_disk.sh
6. 常见问题与注意事项
Q1: 为什么我运行了 fstrim,但 .qcow2 文件大小没变?
A: 这是正常的。
fstrim只是标记块为“空闲”。- qcow2 格式为了性能,不会实时收缩文件。
- 只有在执行以下操作时,物理文件才会真正变小:
- 运行上述的
qemu-img convert -c压缩脚本。 - 创建新快照并删除旧快照(合并过程中会回收)。
- 进行备份还原。
- 运行上述的
- 建议:日常依赖
fstrim保持内部健康,每月运行一次压缩脚本即可。
Q2: 开启 Discard 会影响性能吗?
A: 几乎不会。
- 在现代 SSD 和 PVE 版本上,开销微乎其微。
- 相反,长期不开启会导致 SSD 写入性能下降(写入放大),开启反而能维持高性能。
Q3: 我可以把磁盘大小(Size)从 174G 改回 65G 吗?
A: 极度不推荐,除非万不得已。
- 这需要进入虚拟机内部缩小分区和文件系统,风险极高,容易导致数据丢失或系统无法启动。
- 优势:保持 174G 的逻辑大小,让您未来随时可以写入更多数据而无需再次调整分区,且不占用额外宿主机空间。留着它是最好的选择。
Q4: 脚本运行期间虚拟机不可用吗?
A: 是的。
- 压缩过程需要独占磁盘文件,因此脚本会自动停止虚拟机。
- 请选择业务低峰期(如凌晨)运行。
总结:
- PVE 端:勾选
Discard,IO Thread,SSD。- 虚拟机端:启用
fstrim.timer。- 定期维护:每月运行一次压缩脚本(可选,视数据变动量而定)。
这样即可实现 “逻辑大空间,物理小占用,自动可回收” 的完美状态!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Bai's Blog!
