VMware Thin 卷空间回收:SDelete 与 Storage vMotion 实战
简介围绕 VMware 精简磁盘空间回收这一运维常见问题这份 docx 资料面向虚拟化管理员、存储运维人员及需要处理 Thin 磁盘容量膨胀的读者聚焦 VMFS5 环境下空间无法自动释放、需手动回收的场景。压缩包共 1 个 docx 文件约 408KB内容以文图结合的方式整理便于在实验或生产环境中对照查阅。文中覆盖 SDelete 清理空闲空间后配合 vmkfstools 回收以及通过 Storage VMotion 迁移数据存储释放容量两条思路并对停机要求、目标存储容量、磁盘格式选择等注意事项作出说明。已有 2022 人学习适合希望建立精简卷回收流程、排查 VMDK 占用偏大问题并补充存储运维知识体系的读者参考。1. 先别急着删盘Thin 卷「删了文件不释放」卡在哪一台跑了两三年的文件服务器来宾系统里删掉 9G 历史归档C:盘显示已用降到 27.8G可数据存储上的 vmdk 还稳稳占着 36.7G删掉的空间像被吞了一样。这就是 VMware 精简磁盘空间回收最典型的现场Thin 盘按写入分配块删文件只是来宾文件系统把块标记成空闲ESXi 那一层根本收不到通知vmfs5 又没有自动回收通道块就一直挂在 vmdk 上。回收这套环境的门槛不高真正麻烦的是姿势不对——轻则折腾两小时空间一点没回来重则 datastore 被临时撑爆、虚拟机直接挂起。这篇写给我这类手上管着几台 ESXi、虚拟机大半是 Thin、datastore 余量天天贴着告警线的人。2. 环境盘点vmfs5 与 vmfs6 的回收能力、磁盘格式和停机窗口回收动作本身只有两条命令但踩不踩坑八成分岔在动手之前。同样是 Thin 盘跑在 VMFS-5 和 VMFS-6 上能用的手段不一样同样是删文件有没有快照、目标存储还剩多少决定了你走 SDelete 那条路还是走 Storage vMotion 那条路。所以每次我都先把这三件事查清楚再谈命令。2.1 版本与文件系统先分清 vmfs5 和 vmfs6 能不能自动回收登录 ESXi 主机是第一件事别在 vCenter 界面上猜。SSH 打开后两条命令就能把底摸清一条看主机版本一条看数据存储的文件系统类型和剩余容量。# 登录 ESXi Shell 后执行 vmware -v # 输出示例VMware ESXi 6.0.0 build-3620759 esxcli storage filesystem list # 关注三列Mount Point/vmfs/volumes/...、TypeVMFS-5 / VMFS-6、Freevmware -v给出的是主机构建号用来判断这台机器属于哪一代。esxcli storage filesystem list里的 Type 列是关键显示 VMFS-5说明这套环境没有自动 UNMAP删掉的空间必须手动回收也就是这篇要写的两条路显示 VMFS-6并且主机在 6.5 以后文件系统本身带自动回收能力esxcli storage vmfs unmap -l 数据存储名这类手动命令也能用回收压力小很多。我见过最常见的一种翻车是在 5.5 或 6.0 的主机上照抄 6.7 的自动回收文档敲完命令没反应回头才发现文件系统压根没这个功能。文件系统自动回收手动回收手段我这套环境的实际感受VMFS-3不支持无只能靠迁移重建VMFS-5不支持SDelete vmkfstools -K6.0 起可试esxcli storage vmfs unmap主流老环境两条路都得会VMFS-6支持与主机小版本相关esxcli storage vmfs unmap回收压力小仍要看快照esxcli storage vmfs unmap这条命令在 6.0 以后的 VMFS-5 上也能跑属于比较省事的补充手段但它对「来宾系统已经把块清零」这件事有依赖遇到虚拟机内部大量小文件删除的场景效果往往不如 SDelete 那么干净。所以我一般把它当应急主力还是下面两种方法。2.2 磁盘格式判定Thin、厚置备延迟归零、厚置备立即归零第二件事是确认目标虚拟机到底是不是 Thin。这一点不能只看 vSphere Client 里那个「精简置备」字样最稳的是进到虚拟机目录里直接问 vmkfstools。# 进入虚拟机所在目录先看目录里有哪些 vmdk cd /vmfs/volumes/datastore1/VM-FILE01 ls -lh *.vmdk # 查看某个 vmdk 的详细属性含置备格式 vmkfstools -t0 VM-FILE01.vmdkvmkfstools -t0会打印出磁盘类型、容量和是否精简。ESXi Shell 里显示Thin才是真的 Thin显示VMFS加完整大小那就是厚置备。三种格式的差别直接决定回收路径磁盘格式分配方式删除文件后空间是否自动回来回收走哪条路精简置备 Thin按写入量分配不会方法一或方法二厚置备延迟归零一次分配全量块按需清零不会只能迁移重建厚置备立即归零一次分配并全部清零不会只能迁移重建顺带说一句ls -lh里看到的 vmdk 大小是置备大小不是实际占用真正占了多少要在数据存储浏览器里看「已使用」列或者用du -h在主机上看-flat.vmdk的块占用。这两个数对不上恰恰就是这次要解决的矛盾。2.3 快照、余量与停机窗口回收前的三项检查第三件事是三条硬性前置条件任何一条不满足回收都会中途失败或者把存储撑爆。第一条是快照。虚拟机只要挂着一层快照基础盘就被 delta 文件引用着vmkfstools -K会直接报文件被占用或者打完洞空间纹丝不动。查快照不用开界面目录里扫一眼文件后缀即可。# 目录里出现 -000001、-delta 后缀说明有快照链 ls -lh *-00000*.vmdk *-delta.vmdk 2/dev/null第二条是剩余容量。方法一在 SDelete 阶段会把空闲块全部写零vmdk 会临时膨胀到接近置备大小方法二第一段迁移成厚置备延迟归零目标存储要能完整容纳整块盘。我一般要求目标数据存储剩余空间大于「虚拟机置备大小 × 1.2」这条余量线救过我至少两次。第三条是停机窗口。方法一必须关机方法二是在线迁移但会持续吃存储 IO。生产环境里我把方法一排在凌晨方法二排在业务低峰两者都不建议在备份任务正在跑的时间段内动手否则备份窗口和迁移 IO 会互相拖死。3. 方法一实操SDelete 零填充配合 vmkfstools -K 回收这条路的思路很直白先在来宾系统里把空闲块全部写成零让后端能识别出「这些块是可以丢的」再关机到 ESXi 层把零块打洞释放。两步缺一不可只做第一步 vmdk 只会更大只做第二步没有零块可打。3.1 SDelete 的获取与部署位置SDelete 是微软 Sysinternals 工具集里的命令行程序专门用来清理逻辑磁盘上的空闲空间。它是个绿色单文件不需要安装下载后解压出sdelete64.exe32 位系统用sdelete.exe就行。官方页面在微软 Sysinternals 的 SDelete 条目下地址是https://docs.microsoft.com/zh-cn/sysinternals/downloads/sdelete如果跳转到了新的 learn 域名在 Sysinternals 主页搜 SDelete 一样能找到。部署位置我固定放在C:\Tools\理由有两个一是路径短命令行里少打字符二是这个目录不在系统盘根目录下避免某些安全策略把根目录的可执行文件拦掉。拷进去之后先用-h确认一下版本和参数别等到跑了一半才发现拿错了 32 位版本。# 管理员权限的 PowerShell 里确认工具可用 cd C:\Tools .\sdelete64.exe -h帮助信息里能看到-z、-c、-p、-s、-q这些开关下面这一步只用到-z。3.2 零填充参数sdelete64.exe -z C: 到底做了什么正式执行前我习惯先看一眼各卷的实际使用和剩余确认这次回收大概能拿回多少。# 列出所有本地卷的使用情况 Get-PSDrive -PSProvider FileSystem | Select-Object Name, {nUsedGB;e{[math]::Round($_.Used/1GB,1)}}, {nFreeGB;e{[math]::Round($_.Free/1GB,1)}}然后以管理员身份打开 CMD逐卷执行零填充。注意-z是按卷处理的一块盘跑一次多分区就多跑几次。:: 管理员权限的 CMD 中执行-z 表示把空闲空间全部写零 sdelete64.exe -z C: :: 如果有 D 盘、E 盘单独再跑一遍-z 不会跨卷递归 sdelete64.exe -z D:这个命令的含义可以拆开看sdelete64是 64 位主程序-z是「zero free space」即把文件系统标记为空闲的簇全部写成 0x00已经占用的数据不动。写零的目的是让 VMFS 层能识别出这些块内容全为零后面vmkfstools -K才有东西可打。执行期间会有进度百分比几百 G 的盘跑几个小时很正常中途别 CtrlC。参数作用回收场景是否使用-z空闲空间写零必用回收的核心-c清理空闲空间覆写不用那是安全擦除-p n覆写次数默认 1不用加了只会更慢-s递归子目录清理目录内容时用回收不用-q静默模式放脚本里跑时用-a调整簇对齐一般不动有一个必须提前知道的副作用跑完-z之后虚拟机里的 vmdk 会膨胀到接近置备大小因为在后端看来所有块都被写过一遍。这时候 datastore 的剩余空间会瞬间变少如果本来余量就紧虚拟机可能直接因空间不足挂起。所以我在第 2 章里强调的那条 1.2 倍余量线在这一步就是保命的。3.3 关机后在 ESXi 上执行 vmkfstools -K零填充跑完来宾系统里的活就结束了接下来必须关机。vmkfstools -K要在 vmdk 不被任何进程占用的情况下执行虚拟机开着一定失败。# 来宾系统内正常关机别用强制断电 shutdown /s /t 0确认虚拟机关机后回到 ESXi 侧。SSH 默认是关的如果之前没开先在 vSphere Client 里选中主机配置里找到服务把 SSH 启动或者直接在 DCUI 里开。连上之后进虚拟机目录找到主盘文件名执行打洞。# 进入虚拟机目录确认 vmdk 文件名 cd /vmfs/volumes/datastore1/VM-FILE01 ls -lh VM-FILE01.vmdk VM-FILE01-flat.vmdk # -K 即 --punchzero把 vmdk 中的全零块打洞释放 vmkfstools -K VM-FILE01.vmdk-K是--punchzero的短参数作用是扫描 vmdk 里内容全为零的块把它们从块位图里释放掉vmdk 的实际占用随之下降。命令跑起来后屏幕上会有进度几十 G 的盘通常十几分钟到一小时不等盘越大、零块越分散越慢。期间可以用另一条命令观察占用变化# 每 60 秒看一次实际占用CtrlC 结束观察 while true; do ls -lh VM-FILE01-flat.vmdk; sleep 60; done注意vmkfstools -K一次只处理一个 vmdk。如果虚拟机挂了多块数据盘每块都要单独跑一遍别指望通配符*.vmdk能一把梭——目录里通常还有描述符文件通配符扫进去容易报错中断。3.4 回收过程的观察与中断处理这个方法最难受的地方是不可逆。打洞打了一半中断已经释放的块不会回来vmdk 处于一个「部分回收」的状态虽然不影响虚拟机开机但空间回收得不彻底只能重新跑一遍-K。所以执行前我会做两个动作一是把虚拟机的.vmx和 vmdk 描述符文件备份到别的目录出问题至少能回滚配置二是确认这台虚拟机的备份任务当天已经完成避免回收动作和备份快照撞车。真遇到中途主机重启或者 SSH 断连先别慌重新连上去看 vmdk 大小有没有变化如果没变就重新执行一次-K本身是幂等的重复跑不会破坏数据。4. 方法二实操Storage vMotion 借厚置备延迟归零洗一遍数据第二条路不需要来宾系统里跑任何工具也不要求停机代价是要来回迁移两次且需要一块能装下整盘的目标存储。它的核心思路是利用厚置备格式在迁移过程中重建块分配把已经没用的块丢掉再迁回 Thin 拿回精简收益。4.1 两段式迁移的原理与代价Storage vMotion 迁移虚拟机文件时会按目标格式重新写一遍数据。第一次迁到「厚置备延迟归零」写入过程只搬运有效数据但目标格式要求按完整容量分配块等于把原盘重排了一遍第二次迁回 Thin重排后的盘再按实际使用量分配多余的空间就自然释放了。这个过程的代价要提前算清楚。第一段迁移期间目标存储需要能容纳整块盘属于典型的空间换空间第二段迁回来的时候源和目标都要有空间。整轮下来实际传输的数据量差不多是虚拟机容量的两倍耗时也是两倍。我之前在一台 500G 的盘上做过一次两段加起来接近四个小时中间还赶上备份任务IO 直接被拖慢一半。对比项方法一SDelete vmkfstools -K方法二Storage vMotion是否需要停机需要不需要额外空间要求SDelete 阶段需要盘剩余量需要完整容量的目标存储大致耗时零填充 打洞随盘大小增长两倍数据量传输失败后影响已释放块不可恢复迁移可重试风险更低适合场景单机、能停机、存储紧张在线业务、有第二块存储4.2 第一段迁到厚置备延迟归零动手前先确认目标数据存储的剩余容量这一步别靠界面上的数字估用命令看准确值。# 主机上确认各数据存储的容量和剩余 esxcli storage filesystem list | awk {print $2, $5, $6, $7} # 迁移前记录源 vmdk 的实际占用作为对照基线 cd /vmfs/volumes/datastore1/VM-FILE01 du -h VM-FILE01-flat.vmdk确认目标存储剩余空间大于虚拟机置备容量之后在 vSphere Client 里按下面的步骤操作选中虚拟机右键选择「迁移」。迁移类型选「仅更改存储」不要选「更改计算资源」避免顺带触发主机切换。目标数据存储选那块容量足够的新存储。虚拟磁盘格式选「厚置备延迟归零」Thick Provision Lazy Zeroed。确认后开始迁移在任务面板里盯着进度和 IO。选「厚置备延迟归零」而不是「厚置备立即归零」是因为后者会在迁移过程中把整块盘全量写零耗时能翻好几倍而且这一步的目的只是重排块分配不需要真清零。延迟归零已经足够让后续迁回 Thin 时识别出有效数据。4.3 第二段迁回 Thin 并核对置备大小第一段完成之后虚拟机会停在新存储上磁盘格式是厚置备。这时候如果业务对空间不敏感其实可以就此收手空间已经比原来少占了一些。但如果坚持要 Thin 格式就得再迁一次。第二段的操作路径和第一段一样只是方向反过来目标数据存储选回原来那块磁盘格式改成「精简置备」Thin。这里有个细节容易忽略——迁移回 Thin 时源盘是厚置备VMFS 需要重新计算有效块所以这一段的传输量比第一段小速度通常快一些。# 第二段完成后回原目录核对实际占用是否下降 cd /vmfs/volumes/datastore1/VM-FILE01 ls -lh VM-FILE01-flat.vmdk vmkfstools -t0 VM-FILE01.vmdkvmkfstools -t0的输出里应该能看到Thin字样说明格式确实换回来了。两段迁移都完成后数据存储上显示的「已使用」会明显低于迁移前说明回收成功。4.4 在线迁移的窗口与 IO 影响Storage vMotion 虽然不停机但对存储的压力是实打实的。迁移期间虚拟机的读写延迟会上升跑数据库的机器尤其明显。我一般会把迁移安排在业务低峰并且一次只迁一台不同时开多个迁移任务。另外要留意迁移过程中的告警。如果目标存储的剩余容量逼近临界值vCenter 会给出空间不足的警告这时候及时取消任务还来得及硬撑下去可能导致迁移失败并且留下一堆不完整的文件。取消之后先在数据存储浏览器里清理残留的临时文件再重新规划容量。5. 排查与避坑五条回收现场的血泪记录这套流程我前后做过几十次翻车的次数不少整理成五条都是「看着像玄学查下去全是配置」的类型。5.1 快照没删就敲 vmkfstools -K现象命令执行后立刻报错提示无法打开磁盘文件或者进度条走完了但 vmdk 大小一点没变。原因虚拟机挂着快照链基础盘被-000001.vmdk之类的 delta 文件引用vmkfstools -K拿不到独占访问权即使不报错也只是在操作一个被引用的文件块根本没法释放。解决先关机在快照管理器里删除所有快照并等待合并完成目录里只剩单个 vmdk 和描述符文件后再执行。合并几百 G 的快照本身就要几个小时别省这一步。5.2 SDelete 跑完 vmdk 反而涨满现象零填充之前 vmdk 占用 36G跑完sdelete64.exe -z C:之后涨到接近置备容量 80Gdatastore 告警直接拉响。原因写零等于把原来没写过的块全部写了一遍Thin 盘按写入分配自然全部撑开。这是零填充的必然结果不是出错。解决动手前确认数据存储剩余空间大于虚拟机置备容量的 1.2 倍如果余量不够改走方法二或者先把虚拟机迁到一块大存储上再回收。已经撑爆的尽快执行vmkfstools -K把空间打回来。5.3 SSH 连不上 ESXi现象在终端里连主机 22 端口超时或者被拒绝但 vSphere Client 能正常管理。原因ESXi 的 SSH 服务默认关闭5.5 以后的主机基本都要手动开另外防火墙规则里 sshServer 也可能被禁用了。解决在 vSphere Client 的主机「配置 - 服务」里启动 SSH或者用 DCUI 开启命令行环境下用esxcli network firewall ruleset set -e true -r sshServer打开规则。开启之后用完记得关掉别长期敞着。5.4 回收完 guest 里还是显示占用现象ESXi 侧 vmdk 已经从 36.7G 降到 28G但进到 Windows 里一看C 盘可用空间还是原来那个数。原因打洞回收的是后端块来宾系统的分区表和文件系统元数据没有变化从虚拟机内部看磁盘容量当然没变。另一个常见情况是文件删了却留在回收站里等于没删。解决先清空回收站、清理系统还原点和休眠文件再确认一下是不是分区的已用空间本身就降不下来。要缩小分区得另外做磁盘压缩属于另一件事别和空间回收混为一谈。5.5 选错厚置备立即归零现象方法二第一段迁移跑了十几个小时还没完进度条几乎不动。原因磁盘格式选成了「厚置备立即归零」迁移过程中要把整块盘的每一个块都写零500G 的盘就要写 500G 的零数据。解决取消任务清理目标存储上的残留文件重新迁移时选「厚置备延迟归零」。两者的区别只在清零时机对回收效果没有影响但耗时差好几倍。6. 装完怎么验证四个动作确认空间真的回来了回收做完不等于万事大吉空间有没有真的回来要用四个动作交叉验证只看一个数字很容易被误导。第一个动作是主机侧看实际占用。回到虚拟机目录ls -lh看-flat.vmdk的大小再和动手前记录的du -h数值对比这是最直接的证据。cd /vmfs/volumes/datastore1/VM-FILE01 ls -lh VM-FILE01-flat.vmdk du -h VM-FILE01-flat.vmdk第二个动作是确认磁盘格式没被改坏。用vmkfstools -t0 VM-FILE01.vmdk检查输出里应显示Thin说明还是精简置备下次写满时依然能按需分配。第三个动作是看数据存储的整体水位。在 vSphere Client 的数据存储「摘要」页看已使用和总容量或者用esxcli storage filesystem list看 Free 列和回收前对比。这一步我通常会截图存档方便下次同类操作时对照。验证项命令或位置期望结果vmdk 实际占用du -h xxx-flat.vmdk明显小于回收前记录值磁盘格式vmkfstools -t0 xxx.vmdk显示 Thin数据存储剩余esxcli storage filesystem listFree 列上升虚拟机可用性开机后登录来宾系统文件完整、服务正常第四个动作是开虚拟机验证业务。这一步别跳回收过程虽然不碰数据但关机、迁移这些动作本身有风险。开机后进系统跑一遍关键服务确认文件能正常读写再观察一两天有没有异常告警。从那以后我每次回收前都强制走一遍三查查快照、查余量、查磁盘格式缺一项不动手。这套流程看着啰嗦但比起空间撑爆后连夜扩容多花十分钟确认实在划算。希望帮到你。本文还有配套的精品资源点击获取