PVE 踩坑笔记:精简磁盘 TRIM/DISCARD 开启了,但 LVM-Thin 空洞无法回收,空间不释放
一、故障表现
- VM 磁盘硬件页面,Discard(丢弃)选项已经勾选
- Linux 虚拟机内支持 TRIM,
fstrim -av执行没有报错,提示若干字节已裁剪 - Windows 虚拟机开启了 SSD 优化、TRIM
- 虚拟机内删除大文件,df 查看分区空闲空间变大
- 宿主机
lvs查看 thinpool 的 Data% 占用没有下降,空闲空间不增加 - 重建虚拟机、重新挂载磁盘,现象依旧;只有备份迁移到厚盘再迁回,才能临时释放
- 快照数量不多,排除快照锁定块的简单场景
典型特征:客户机 TRIM 命令执行成功,但宿主机精简存储没有回收空洞,TRIM 链路断在中间环节。
二、原理简单说明
PVE 下虚拟机 TRIM 是多层协同机制:
- 客户机文件系统:删除文件,向块设备发送 discard 请求;
- QEMU 层:接收客户机的 discard 命令,转发给后端存储(LVM-Thin/RBD);
- 宿主机精简存储层:收到丢弃指令,释放对应的块,thinpool 空闲空间增加。
三层缺一不可。Web 界面的 Discard 选项,只是打开 QEMU 接收 discard 请求的开关。 很多场景下,请求被上层拦截、或者后端不支持、或者块被快照引用,就算客户机执行 trim,宿主机也不会释放空间。
三、排查顺序
- 先在虚拟机内验证文件系统是否真正支持 discard
# Linux虚拟机
lsblk -D
DISC-GRAN、DISC-MAX 不为 0,代表块设备支持 discard;为 0 则客户机层面不支持。
- 查看虚拟机磁盘配置,确认 discard 选项
qm config 100
磁盘参数看是否带有 discard=on
- 确认虚拟机是否有快照占用这些块
qm listsnapshot 100
只要快照存在,快照引用的数据块不能被 TRIM 回收。
- 宿主机层面,检查 thin 的 discard 支持
# 查看thinpool是否支持discard
thin_check /dev/pve/thinpool
- 实时观察 trim 执行时宿主机存储变化
watch -n2 lvs
虚拟机执行 fstrim 的同时观察 Data% 是否变化。
四、分场景修复方案
场景 1:存在未删除快照(最高频)
快照会保留历史数据块,只要快照存在,这些块被快照引用,TRIM 无法释放。哪怕虚拟机里删掉文件,旧块还要留给快照,thin 池空间不会释放。
验证:删除测试快照,再执行 fstrim 观察空间。
重点坑:很多人认为快照只占用增量,原始块依然可以 trim,这个理解是错的。只要快照链引用该块,块不能回收。
处理方案:
- 及时清理过期无用快照;
- 业务上不要长期保留大量快照;
- 备份优先使用 PBS 备份,而不是依赖虚拟机快照。
场景 2:QEMU Discard 模式选错,unmap 没有开启
PVE 的 Discard 分为两种行为:
discard=on:客户机发送 discard,QEMU 转发 unmap 到后端存储(需要后端支持)- 只勾选 discard,但后端存储不支持 unmap,请求直接丢弃
LVM-Thin 支持 unmap;老版本部分外部存储不支持。
检查:
qm config 100 | grep scsi
确认参数是 discard=on。
注意:SATA、IDE 磁盘对 discard 支持差,优先使用 VirtIO-Block。VirtIO-SCSI 对 TRIM 支持更好。
场景 3:文件系统挂载参数没有开启 discard(实时 discard vs 手动 fstrim)
两种 TRIM 模式:
- 实时 discard:挂载参数添加
discard,删除文件立刻下发;性能差,不推荐; - 定时 fstrim:默认推荐,定时任务批量下发 trim 请求,主流方案。
检查挂载参数:
mount | grep /
就算不加 discard 挂载参数,只要块设备支持,手动
fstrim依然可以工作。 坑:部分老内核、特殊文件系统(部分加密 fs、xfs 旧版本)对 trim 支持有 bug。
场景 4:使用 VirtIO-SCSI 但没有开启 unmap
VirtIO-SCSI 需要额外一个参数 unmap=1,很多人只开 discard,漏掉这个。 修改 VM 磁盘参数:
qm set 100 --scsi0 local-lvm:vm-100-disk-0,discard=on,unmap=1,size=32G
VirtIO-Block 不需要 unmap 参数,VirtIO-SCSI 必须搭配 unmap 才能正常转发 trim。这是非常容易踩漏的参数。
场景 5:LVM-Thin 的 thinpool 没有开启 discard 支持 / 内核版本过低
低版本 Linux 内核,thin-provisioning-tools 版本旧,unmap 处理存在 bug,收到 trim 请求不释放块。 查看 thin 工具版本:
thin_check --version
升级 proxmox 内核和 thin-provisioning-tools 到官方稳定版。
场景 6:磁盘是克隆导入、块有残留分配标记
从外部镜像导入、ova 导入的虚拟机磁盘,块分配表存在大量预分配块,客户机删除文件也无法回收。 处理:
- 虚拟机内完整 fstrim;
- 必要时新建空白精简盘,rsync 迁移数据到新盘,旧盘删除。
场景 7:Windows 虚拟机 TRIM 不生效
Windows:
- 确认识别为 SSD;
- 开启 “优化驱动器”,定时 TRIM;
- 老 virtio-win 驱动对 unmap 支持缺陷,升级 virtio 驱动。
五、验证修复
清理快照、补齐 unmap 参数后,在虚拟机执行:
fstrim -av
同时宿主机监控 lvs,thinpool Data% 下降,空闲空间上涨,代表 TRIM 链路全部打通。
六、高频踩坑点
- 只在 Web 页面勾选 Discard 就认为完成配置,不知道 VirtIO-SCSI 还需要
unmap=1; - 忽略快照会锁定数据块,TRIM 再怎么跑也释放不了快照占用空间;
- 混淆 VirtIO-Block 和 VirtIO-SCSI 参数差异,一套配置到处套用;
- 实时挂载 discard 开启,带来随机写性能下降,还误以为是存储卡顿;
- thin-provisioning-tools 版本老旧,存在 unmap 处理 bug,很难定位。
七、排坑总结
- TRIM 回收是一条端到端链路:客户机文件系统 → QEMU (discard/unmap) → thin 存储;一环失效就无法回收;
- 排查顺序优先:检查快照 → 确认磁盘控制器类型,补齐 unmap 参数 → 验证虚拟机 lsblk -D → thin 工具版本;
- VirtIO-SCSI 适合数据库、需要稳定 TRIM 的业务,但是记住要加 unmap=1;
- 不要依赖实时 discard 挂载参数,生产推荐使用 systemd 定时 fstrim;
- 快照是 TRIM 回收最大阻碍,精简存储环境,快照策略一定要收敛。
- 点赞
- 收藏
- 关注作者
评论(0)