PVE 踩坑笔记:精简磁盘 TRIM/DISCARD 开启了,但 LVM-Thin 空洞无法回收,空间不释放

举报
Auunes 发表于 2026/10/26 09:20:56 2026/10/26
【摘要】 一、故障表现VM 磁盘硬件页面,Discard(丢弃)选项已经勾选Linux 虚拟机内支持 TRIM,fstrim -av 执行没有报错,提示若干字节已裁剪Windows 虚拟机开启了 SSD 优化、TRIM虚拟机内删除大文件,df 查看分区空闲空间变大宿主机 lvs 查看 thinpool 的 Data% 占用没有下降,空闲空间不增加重建虚拟机、重新挂载磁盘,现象依旧;只有备份迁移到厚盘再...

一、故障表现

  • VM 磁盘硬件页面,Discard(丢弃)选项已经勾选
  • Linux 虚拟机内支持 TRIM,fstrim -av 执行没有报错,提示若干字节已裁剪
  • Windows 虚拟机开启了 SSD 优化、TRIM
  • 虚拟机内删除大文件,df 查看分区空闲空间变大
  • 宿主机 lvs 查看 thinpool 的 Data% 占用没有下降,空闲空间不增加
  • 重建虚拟机、重新挂载磁盘,现象依旧;只有备份迁移到厚盘再迁回,才能临时释放
  • 快照数量不多,排除快照锁定块的简单场景

典型特征:客户机 TRIM 命令执行成功,但宿主机精简存储没有回收空洞,TRIM 链路断在中间环节。

二、原理简单说明

PVE 下虚拟机 TRIM 是多层协同机制:

  1. 客户机文件系统:删除文件,向块设备发送 discard 请求;
  2. QEMU 层:接收客户机的 discard 命令,转发给后端存储(LVM-Thin/RBD);
  3. 宿主机精简存储层:收到丢弃指令,释放对应的块,thinpool 空闲空间增加。

三层缺一不可。Web 界面的 Discard 选项,只是打开 QEMU 接收 discard 请求的开关。 很多场景下,请求被上层拦截、或者后端不支持、或者块被快照引用,就算客户机执行 trim,宿主机也不会释放空间。

三、排查顺序

  1. 先在虚拟机内验证文件系统是否真正支持 discard
# Linux虚拟机
lsblk -D

DISC-GRAN、DISC-MAX 不为 0,代表块设备支持 discard;为 0 则客户机层面不支持。

  1. 查看虚拟机磁盘配置,确认 discard 选项
qm config 100

磁盘参数看是否带有 discard=on

  1. 确认虚拟机是否有快照占用这些块
qm listsnapshot 100

只要快照存在,快照引用的数据块不能被 TRIM 回收。

  1. 宿主机层面,检查 thin 的 discard 支持
# 查看thinpool是否支持discard
thin_check /dev/pve/thinpool
  1. 实时观察 trim 执行时宿主机存储变化
watch -n2 lvs

虚拟机执行 fstrim 的同时观察 Data% 是否变化。

四、分场景修复方案

场景 1:存在未删除快照(最高频)

快照会保留历史数据块,只要快照存在,这些块被快照引用,TRIM 无法释放。哪怕虚拟机里删掉文件,旧块还要留给快照,thin 池空间不会释放。

验证:删除测试快照,再执行 fstrim 观察空间。

重点坑:很多人认为快照只占用增量,原始块依然可以 trim,这个理解是错的。只要快照链引用该块,块不能回收。

处理方案:

  1. 及时清理过期无用快照;
  2. 业务上不要长期保留大量快照;
  3. 备份优先使用 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 模式:

  1. 实时 discard:挂载参数添加 discard,删除文件立刻下发;性能差,不推荐;
  2. 定时 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 导入的虚拟机磁盘,块分配表存在大量预分配块,客户机删除文件也无法回收。 处理:

  1. 虚拟机内完整 fstrim;
  2. 必要时新建空白精简盘,rsync 迁移数据到新盘,旧盘删除。

场景 7:Windows 虚拟机 TRIM 不生效

Windows:

  1. 确认识别为 SSD;
  2. 开启 “优化驱动器”,定时 TRIM;
  3. 老 virtio-win 驱动对 unmap 支持缺陷,升级 virtio 驱动。

五、验证修复

清理快照、补齐 unmap 参数后,在虚拟机执行:

fstrim -av

同时宿主机监控 lvs,thinpool Data% 下降,空闲空间上涨,代表 TRIM 链路全部打通。

六、高频踩坑点

  1. 只在 Web 页面勾选 Discard 就认为完成配置,不知道 VirtIO-SCSI 还需要 unmap=1;
  2. 忽略快照会锁定数据块,TRIM 再怎么跑也释放不了快照占用空间;
  3. 混淆 VirtIO-Block 和 VirtIO-SCSI 参数差异,一套配置到处套用;
  4. 实时挂载 discard 开启,带来随机写性能下降,还误以为是存储卡顿;
  5. thin-provisioning-tools 版本老旧,存在 unmap 处理 bug,很难定位。

七、排坑总结

  1. TRIM 回收是一条端到端链路:客户机文件系统 → QEMU (discard/unmap) → thin 存储;一环失效就无法回收;
  2. 排查顺序优先:检查快照 → 确认磁盘控制器类型,补齐 unmap 参数 → 验证虚拟机 lsblk -D → thin 工具版本;
  3. VirtIO-SCSI 适合数据库、需要稳定 TRIM 的业务,但是记住要加 unmap=1;
  4. 不要依赖实时 discard 挂载参数,生产推荐使用 systemd 定时 fstrim;
  5. 快照是 TRIM 回收最大阻碍,精简存储环境,快照策略一定要收敛。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。