资讯详情

资讯详情

VMware Thin磁盘空间回收:SDelete与Storage vMotion实战

简介面向 VMware 虚拟化运维人员的一份精简磁盘空间回收实操文档聚焦 vmfs5 文件系统不支持自动回收、Thin 磁盘删除文件后 VMDK 仍占用宿主机容量的常见困扰。压缩包仅 408KB内含 1 个 docx 文件围绕两条回收路径展开一是借助微软 SDelete 清零 Windows 虚拟机空闲空间关机后通过 SSH 登录 ESXi 主机执行 vmkfstools -K 回收 VMDK二是用 Storage VMotion 在线迁移将磁盘格式改为厚置备延迟归零以释放空间再迁回 Thin 保持精简。文中还交代了停机执行命令的前提、目标存储容量校验等易错细节并给出磁盘实际占用 27.8G 而 VMDK 达 36.7G 的案例数据便于对照判断是否命中同类问题。已有 2021 人学习适合需要处理存储告警、优化 Thin 卷占用的中初级虚拟化运维人员参考。1. 一块 36.7G 的 VMDK 只装了 27.8G 数据Thin 磁盘空间去哪了整理一套测试环境的存储容量时我翻出一台 Windows Server 2012 R2 虚拟机系统里看实际只用了 27.8G数据存储上那个 VMDK 却实打实占着 36.7G。既不是快照也不是内存交换文件就是我前阵子在里面删掉的一批日志和安装包——文件在 Guest OS 里没了VMFS 上的块还挂着。这就是 VMware Thin 精简置备最典型的「只涨不跌」写入时按需分配删除时没人通知底层。要把它收回来绕不开两条路一是在系统里把空闲块清零再让 ESXi 回收二是用 Storage vMotion 搬一趟把空洞挤掉。下面按我实际操作的顺序把两条路的命令、参数、耗时和翻车点都摊开讲环境以 ESXi 主机加 vCenter、Guest 为 Windows Server 2012 R2 为基准其他版本差异我会单独标出来。2. 先把账算清Thin、厚置备与 VMFS 回收的底层逻辑动手之前得先搞明白一件事你看到的「虚拟机里用了 27.8G」和「存储上占了 36.7G」统计的压根不是同一层的东西。前者是 NTFS 的文件系统账本后者是 VMFS 数据块分配表。中间隔着一层虚拟磁盘格式账对不上是常态对上了才是巧合。这一章不讲操作只把后面两条路线的判断依据立住否则照着命令敲一遍出问题时你连该看哪个日志都不知道。2.1 Thin 磁盘为什么会「涨上去就下不来」精简置备的分配逻辑是写时分配Guest OS 第一次往某个偏移写入数据ESXi 才在 VMFS 上真正划出对应的块并建立映射。一台 100G 的 Thin 虚拟机刚建好时可能只占几百兆随着业务写入慢慢涨这个方向是单向的。问题出在反向——当 Guest OS 删除一个文件NTFS 做的事只是把簇标记为可用、改一改 MFT 记录它根本不知道、也没有义务告诉下面的 hypervisor「这几块我不要了」。于是 VMFS 侧的映射表原封不动那些块仍然算在这台虚拟机头上。你在系统里删了 9G 日志VMDK 一个字节都不会缩。更麻烦的是这些「幽灵块」会被后续写入复用但复用是随机的磁盘上形成大量空洞实际占用和真实数据量越拉越开。我见过最夸张的一台文件服务器置备 500G、系统内实际 120G、VMDK 占 480G剩下那 360G 全是历年删删写写留下的碎片。这里有个容易被忽略的细节Thin 的回收粒度不是文件级的。哪怕你在系统里只删了一个 10G 的镜像文件只要这 10G 在虚拟磁盘上不是连续的、对齐的整块区域回收工具也只能按块处理能吐回来的可能只有七八个 G。所以回收前先用系统自带工具做一次碎片整理或者至少确认没有大范围碎片对最终效果影响不小——这一步很多人跳过然后抱怨「清了半天只回来一点点」。还有一类「假 Thin」值得单独点出来磁盘格式显示是 Thin但虚拟机上挂着快照。此时写入落在 delta 文件里基础盘被锁成只读你后面做的任何清零和回收动作都作用不到真正的数据盘上。查快照是回收前的第一件事比看容量还优先。2.2 VMFS5 与 UNMAP为什么自动回收指望不上理论上这事有标准解法SCSI 协议里有个 UNMAP 命令ATA 世界叫 TRIM允许 Guest OS 主动告诉存储层「这些块空了你收回去」。VMware 在 VMFS 上实现了这套机制但默认状态下它基本等于没开原因很实在早期版本里 UNMAP 是同步阻塞执行的一次大规模删除可能让整台主机的 I/O 卡住几十秒严重影响同数据存储上的其他虚拟机。所以 ESXi 给了一堆开关默认值偏保守。想确认你这台主机到底是什么状态SSH 上去查# 列出 /VMFS3 下与块删除、UNMAP 相关的所有高级参数及当前值 # 不同 ESXi 版本参数名略有差异用关键词过滤最稳 esxcli system settings advanced list -o /VMFS3 | grep -iE delete|discard|unmap # 单独看某个参数示例实际名称以你环境上一条命令的输出为准 esxcli system settings advanced get -o /VMFS3/EnableBlockDeleteEnableBlockDelete控制的是 VMFS 层的块删除通知EnableDiscards一类参数控制是否把 Guest 的 discard 请求透传下去。代码里我特意没有写死参数全名因为这几个开关在 ESXi 5.5、6.0、6.5、7.x 上叫法和默认值都动过照抄网上某篇老文章的路径大概率扑空。先list再get是血泪经验。即便你把开关全打开还有两道坎。第一道在 Guest 侧Windows 直到 Server 2012 之后才对虚拟磁盘的 UNMAP 有像样的支持而且需要 Guest 内的磁盘控制器驱动配合老系统直接没戏。第二道在性能即使异步化之后大规模 UNMAP 仍然会带来可观的元数据开销生产环境里 DBA 和存储管理员通常都不愿意在业务高峰做这件事。VMFS6ESXi 6.5 起在这方面做了改进自动 UNMAP 是默认开启的粒度也从 1MB 细化到更小。但它是「延迟回收」删除之后要等一段时间才真正生效而且回收期间对 I/O 有影响。所以哪怕在 VMFS6 环境遇到容量告急、需要立刻拿回空间的场景手动回收依然是更快更可控的选择。判断标准很简单你要的是「最终会回收」还是「今天下午就要腾出 80G」前者可以等后者必须手动上。2.3 两条路线的选型停机清零 vs 在线迁移搞清楚原理之后两条路线的取舍其实很清楚。方法一走的是「让 Guest 主动把空闲块写成 0再由 ESXi 把这些全零块剔除」的路子本质上是用一次全盘写入换一次精确回收。方法二走的是「把虚拟机整体搬到另一个数据存储搬的过程中只复制有效数据」的路子空洞在搬运途中自然消失。我把实际运维中要权衡的几个维度列成表你可以直接对着自己的场景选对比维度SDelete vmkfstools -KStorage vMotion 两次迁移是否需要停机需要回收命令要求虚拟机完全关机不需要在线迁移额外存储需求无原地回收需要目标存储能放下整个置备容量典型耗时30G 级清零 13 小时回收 2060 分钟单次迁移 3090 分钟两跳累计翻倍对业务 I/O 的影响清零阶段 Guest 磁盘压力大迁移阶段源和目标存储带宽压力大最终磁盘格式保持 Thin 不变取决于第二次迁移选的格式可回到 Thin适用场景单机维护窗口、存储余量紧张业务不能停、有富余存储或可临时借用选型上我一般这么判断如果这台机器有明确维护窗口、且数据存储本身快满了腾不出第二份空间走方法一虽然慢但不需要额外容量。如果业务 7×24 不能停或者数据存储余量充足、甚至有另一套存储可以做临时落脚点走方法二代价是两次迁移的带宽和时间。方法二有个变种值得提一句如果你本来就要把虚拟机迁到新存储上那顺手把第一次迁移的格式选成厚置备延迟归零、落位到目标存储空间在这一次迁移里就释放了等于白捡一次回收不需要再迁回来。只有当你必须留在原来的 Thin 数据存储上时才需要走完整的两跳。还有一条不怎么上台面但确实存在的野路子直接用vmkfstools克隆一份新磁盘再替换。本质上和迁移是一回事但中间态更难管理出错回滚成本高除非你对这台虚拟机的磁盘布局非常熟否则我不推荐。下面两章分别把两条主路线拆到能照着敲的程度。3. 方法一实战SDelete 归零 vmkfstools -K 两步走这条路线的核心思路是把「哪些块是空的」这个信息从 Guest OS 的模糊认知变成 ESXi 能识别的确定信号——空闲块全部写成 0vmkfstools -K扫到连续全零的块就直接从映射表里摘掉。两步缺一不可只做清零不做回收空间一点都不会变只做回收不做清零工具会认为满盘都是有效数据。3.1 在 Guest OS 内跑 SDelete命令、参数与耗时估算SDelete 是 Sysinternals 套件里的命令行工具微软官方站点可以下到解压出来就一个sdelete64.exe32 位系统用sdelete.exe。它会往磁盘上空闲簇写入指定模式的垃圾数据再清零对虚拟磁盘来说这一步的唯一目的就是让那些块变成「一眼能看出是空的」。先把工具丢到系统盘根目录用管理员权限开 CMD。上来先看帮助确认参数——这不是客套SDelete 各版本参数有过调整尤其是覆盖次数相关的选项:: 管理员权限运行先确认参数拼写与当前版本支持项 C:\sdelete64.exe /? :: -z 表示清零空闲空间zero free space-p 指定覆盖遍数 :: 对虚拟磁盘场景覆盖 1 遍足够默认 3 遍纯属浪费三倍时间 C:\sdelete64.exe -z C: -p 1 :: 多分区环境逐个执行别指望一条命令扫全盘 C:\sdelete64.exe -z D: -p 1-z是关键参数它的语义是「清零空闲空间」而不是「安全擦除文件」后者用-c或-s配合路径。-p 1把覆盖遍数压到一遍原因很直接SDelete 的多次覆盖是为物理磁盘防恢复设计的而在虚拟机里ESXi 判断块是否可回收只看内容是不是全零你覆盖三遍它也只认最后一遍的结果白白多花两倍时间。-accepteula这个参数建议加上否则首次运行会弹一个许可协议窗口等你点同意脚本化执行时直接卡死在那儿。另外记得关掉系统的卷影副本和备份任务VSS 快照占用的块不会被 SDelete 当作空闲空间也不会被后续回收释放这是最常见的「清了等于没清」的原因。耗时方面给个参考全盘写入的速度受限于数据存储的写带宽和 Guest 内磁盘队列深度SATA 级别的虚拟盘大约 3060 MB/sSSD 后端能到 200 MB/s 以上。一台实际使用 27.8G、置备 40G 的虚拟机需要清零的空闲空间约 12G机械盘后端差不多要跑一到一个半小时。进度条走完之后别急着关机让系统把缓存刷干净。提示清零期间虚拟机的写 I/O 会持续处于高位如果这台机器和其他业务共用同一数据存储尽量安排在低峰期。清零过程中磁盘剩余空间可能短暂变小这是正常现象。3.2 关机后 SSH 进 ESXi定位 VMDK 与 vmkfstools -K 的真实行为清零做完接下来必须把虚拟机关掉。这一点没有商量余地——vmkfstools -K需要独占打开 VMDK 文件并修改其块映射虚拟机运行时会持有文件锁命令会直接失败退出。我见过有人图省事用挂起Suspend状态去执行同样拿不到锁。先在 vSphere Client 里把虚拟机关机然后开启 ESXi 主机的 SSH 服务。图形界面的路径是选中主机 → 配置 → 系统 → 服务 → 找到 SSH → 启动如果你只有 DCUI 命令行界面也可以在主机的物理控制台上操作。SSH 开启后从跳板机登进去# 登录到虚拟机所在的那台 ESXi 主机 ssh root192.168.10.21 # 列出所有数据存储确认虚拟机落在哪个卷上 esxcli storage filesystem list # 进入虚拟机目录路径里的卷名和虚拟机名换成你实际的 cd /vmfs/volumes/ds-thin-01/win2012-test # 看清目录下到底有哪些 vmdk别对描述符文件动手 ls -lh *.vmdkls这一步非常关键。一个正常的虚拟机目录里你会看到win2012-test.vmdk小文件几百字节到几 KB这是描述符和win2012-test-flat.vmdk大文件真正存数据的。-K参数要作用在描述符文件上也就是那个小的.vmdkvmkfstools 会自动关联到对应的 flat 文件。如果你对着-flat.vmdk敲命令工具会报错或者行为异常。目录里如果还有-000001.vmdk这种带数字后缀的说明存在快照必须先处理掉否则回收的是快照层基础盘纹丝不动。确认无误后执行回收# -K 即 punch zero扫描 VMDK 中全零的块并从映射表摘除 # 参数必须是描述符文件不是 -flat.vmdk vmkfstools -K win2012-test.vmdk # 部分版本用长参数写法效果一致 vmkfstools --punchzero win2012-test.vmdk命令跑起来后会显示进度百分比。这个过程只读不写业务数据但需要遍历整个虚拟磁盘的块映射表3040G 的盘通常 1040 分钟具体取决于数据存储的元数据操作性能和后端是不是机械盘。中途不要 CtrlC中断可能留下不一致的映射状态虽然一般不至于损坏数据但会让你搞不清到底回收了多少。跑完之后我习惯再确认一次文件的实际占盘量# du 统计的是 VMFS 上真实分配的块数和 ls 显示的逻辑大小不是一回事 du -h win2012-test-flat.vmdk # 对照整个目录的总占用 du -sh /vmfs/volumes/ds-thin-01/win2012-testls -lh看到的永远是置备容量比如 40G因为这个数字写在描述符里不会变。真正反映回收效果的是du它读的是文件系统实际分配的块。这两个数字的差值就是这轮操作省下来的空间。3.3 验证效果怎么确认空间真的回来了回收跑完别急着开机交付。先在 ESXi 侧和 vCenter 侧各核对一遍两边数据对得上才算数。ESXi 侧的核对用上面那条du就够了。vCenter 侧看的是虚拟机的存储摘要选中虚拟机 → 摘要 → 存储里面有「已使用空间」和「已置备空间」两个值。回收成功的标志是已使用空间明显下降、向 Guest 内的实际用量靠拢。如果关机前是 36.7G、清零回收后变成 28.5G 左右说明这轮干得不错如果纹丝不动回去查三件事快照有没有清干净、SDelete 是不是真跑完了、回收命令作用的文件对不对。还有一点容易误判某些版本的 vCenter 统计有缓存延迟回收完立刻刷新可能数字没变等几分钟或者对虚拟机做一次重新扫描Rescan Datastore再看。我遇到过一次以为失败、准备重跑结果五分钟后再刷数字已经对了白紧张一场。开机之后建议观察一两天再把这个流程写进运维手册。有些业务在清零后会触发大量的首次写入Thin 磁盘又会慢慢涨回去一部分这是正常的——涨回去的是真实写入的数据不是幽灵块。判断标准不是「涨没涨」而是「涨到的位置和 Guest 内实际用量是否匹配」。注意如果你的数据存储是 VMFS6 且自动 UNMAP 已开启手动回收完成后的一段时间里可能还会看到零星的空间下降那是后台延迟回收在收尾属正常现象不用重复执行。4. 方法二实战Storage vMotion 两次迁移把 Thin 榨干停机回收的问题不在于技术难度而在于那个维护窗口往往排不上。这时候 Storage vMotion 就是救命稻草虚拟机全程在线数据从源存储搬到目标存储的过程中只有真正的有效数据会被复制过去空洞在传输途中自动消失。代价是你得有一块能放下整台虚拟机的地方。4.1 迁移前的前置检查目标存储余量与格式选择这一章最容易翻车的地方不在操作在算容量。很多人以为「源存储上这台虚拟机只占 30G那目标存储有 40G 就够了」结果迁移到 92% 卡住失败。原因在于你第一次迁移选的是厚置备Thick格式它按置备容量分配空间不是按实际使用量。假设虚拟机置备 200G、实际用了 120G你要把它迁成厚置备延迟归零目标存储就必须实打实腾出 200G。迁移过程中源端的 VMDK 还没删等于同一时间存在两份源端占着 120G、目标端占着 200G。所以容量检查要盯三个数置备容量、源端实际占用、目标存储剩余可用空间。具体检查清单我一般这么过一遍目标存储可用空间 ≥ 虚拟机置备容量 × 1.05留 5% 余量给快照文件和交换文件。虚拟机没有未合并的快照。有快照时迁移只搬当前活动的 delta合并后可能又涨回去。虚拟机的 CD/DVD 驱动器没有挂载物理客户端设备或 ISO 镜像这类挂载在迁移时经常报「设备或文件不可访问」。源主机和目标主机在同一 vCenter 下且 CPU 厂商一致或开启了 EVC 基线。跨厂商 CPU 集群的热迁移会被直接拒绝。目标存储的块大小、VMFS 版本能容纳这台虚拟机的最大磁盘文件。VMFS5 单文件上限 62TB 基本不用担心但如果目标是 NFS 就要确认挂载参数。这些检查用 PowerCLI 一条命令就能扫个大概比起在界面里一个个点开看快得多# 连接 vCenter地址换成你环境的 Connect-VIServer -Server vcenter.example.local -User adminexample.local # 看目标数据存储的剩余容量GB Get-Datastore -Name ds-thick-01 | Select-Object Name, {nFreeGB;e{[math]::Round($_.FreeSpaceGB,1)}}, {nCapacityGB;e{[math]::Round($_.CapacityGB,1)}} # 看虚拟机的置备容量和实际占用以及有没有快照 $vm Get-VM -Name win2012-test $vm | Select-Object Name, ProvisionedSpaceGB, UsedSpaceGB, {nSnapshots;e{($_ | Get-Snapshot).Count}}ProvisionedSpaceGB是虚拟机所有磁盘的置备容量之和UsedSpaceGB是 VMFS 上真实占用的块两者之差就是你能收回来的理论上限。Get-Snapshot返回非空就得先把快照合并掉否则这趟迁移等于白搬。4.2 第一跳迁到厚置备延迟归零第一次迁移的目标不是回收空间而是把虚拟磁盘从「带空洞的 Thin」变成「没有空洞的 Thick」——厚置备在创建时就把整个容量写满零块数据的物理布局是紧凑连续的没有任何空洞残留。延迟归零Lazy Zeroed和全零厚置备Eager Zeroed Thick的区别在于零块是「按需写」还是「立刻写」前者的迁移速度快得多后者更安全但耗时可能翻几倍。日常回收用延迟归零就够。图形界面的路径是选中虚拟机 → 右键 → 迁移 → 选择「仅更改存储」→ 目标数据存储选厚置备那块卷 → 虚拟磁盘格式下拉框选「厚置备延迟归零」→ 下一步确认 → 完成。整个过程虚拟机会在线唯一能感知到的是磁盘 I/O 在高负载时段可能略有抖动。我更习惯用 PowerCLI 做一来参数明确不容易点错二来可以顺手记日志# 第一跳Thin - 厚置备延迟归零把空洞填实 # -DiskStorageFormat Thick 对应界面上的「厚置备延迟归零」 Move-VM -VM (Get-VM -Name win2012-test) -Datastore (Get-Datastore -Name ds-thick-01) -DiskStorageFormat Thick -Confirm:$false # 迁移是异步任务等它真正结束再进下一步 Get-Task | Where-Object {$_.State -eq Running} | Wait-Task-DiskStorageFormat有三个取值要分清Thin精简、Thick厚置备延迟归零、EagerZeroedThick厚置备全零。选Thick意味着目标端立刻按置备容量划走空间这也是为什么前置检查要那么严格。-Confirm:$false是跳过确认提示批量场景下有用手工单台执行时我一般留着确认多一次复核机会。迁移进度在 vSphere Client 的「近期任务」里能看到百分比。卡在某个数字几分钟不动是正常的尤其是接近尾声的时候ESXi 在做磁盘链的切换和源端清理。我遇到过卡在 92% 停了将近十分钟当时以为挂了结果只是源端的块清理耗时。判断是否真卡死的办法是看主机性能图表里目标存储的写带宽只要还有读写流量就说明在干活。4.3 第二跳迁回 Thin 并核对真实占用第一跳完成之后虚拟机的 VMDK 是一个没有空洞的厚置备文件占满整个置备容量。这时候如果你接受厚置备流程就结束了——空间确实从「36.7G 的虚胖 Thin」变成了「40G 的厚盘」但总占用反而变大了没有任何意义。真正把空间收回来的动作在第二跳迁回原来的 Thin 数据存储格式选回 Thin。# 第二跳厚置备 - Thin此时源盘没有空洞转 Thin 后只占实际数据量 Move-VM -VM (Get-VM -Name win2012-test) -Datastore (Get-Datastore -Name ds-thin-01) -DiskStorageFormat Thin -Confirm:$false # 迁回后核对实际占用 Get-VM -Name win2012-test | Select-Object Name, ProvisionedSpaceGB, UsedSpaceGB第二跳的原理和第一跳对称源端是一块紧凑的厚盘数据块连续排列转换目标格式为 Thin 时ESXi 只为有效数据分配块于是 40G 的厚盘落地成 28G 的 Thin。整个过程虚拟机同样在线不需要停机。有个细节值得注意第二跳必须等第一跳彻底完成、源端 VMDK 已经清理干净才能开始否则会出现「迁移任务排队中」的等待白白浪费时间。上面的Wait-Task就是干这个的。另外如果你的目标存储和源存储是同一块物理设备的不同逻辑卷两跳之间的数据搬运其实是设备内部的速度会快很多这时候两跳的总耗时可能比单跳还短。迁完之后立刻核对。UsedSpaceGB应该明显低于ProvisionedSpaceGB且和 Guest 内系统看到的用量接近。如果两个数字还贴着八成是第一跳选的格式不对比如误选了 EagerZeroedThick某些场景下转换会保留原有分配或者是第二跳的目标存储被识别成了厚置备。用Get-HardDisk确认磁盘的StorageFormat属性最终是Thin这一步别省# 逐块盘确认格式多磁盘虚拟机要每块都对 Get-VM -Name win2012-test | Get-HardDisk | Select-Object Name, CapacityGB, StorageFormat, FilenameFilename会显示 VMDK 的完整路径路径里的卷名能反向验证它到底落在了哪块数据存储上。多磁盘虚拟机经常出现「系统盘迁过去了、数据盘还在原地」的情况多半是当初只勾选了部分磁盘。用这条命令一次看全比在界面里翻强。5. 避坑与排查这五种翻车我见过不止一次前面两章给的是「一切顺利时怎么做」但回收这件事的失败率其实不低因为它依赖一个跨越 Guest OS、虚拟化层、存储层三层的状态一致性。任何一层有信息没同步结果就是白忙一场。下面五条是我和同事实际踩过的每条按现象、原因、解决三段写遇到对应症状直接对号入座。5.1 空间纹丝不动先查快照与卷影副本现象SDelete 从头跑到尾、vmkfstools -K也显示 100% 完成回头一看 VMDK 占用一个字节没少。原因排在最前的是快照。虚拟机存在快照时所有新写入都落到-000001.vmdk这个 delta 文件里基础盘的块映射被冻结-K就算扫到全零块也改不了基础盘的映射表。第二常见的是 Windows 卷影副本VSS系统还原点、备份软件留下的快照、文件服务器上的「以前的版本」这些占用的块在 NTFS 看来是有效数据SDelete 不会碰自然也就回收不掉。第三种是 pagefile 和 hiberfil 这类被系统独占的巨型文件它们占的块同样不在空闲空间之列。解决先vim-cmd vmsvc/snapshot.get vmid或界面里确认快照已全部删除并合并。然后在 Guest 内跑vssadmin list shadows看有没有残留的卷影副本确认不需要之后用vssadmin delete shadows /forC: /all清掉。pagefile 不用管它占的空间本来就是真实需要的硬要回收只能关机后挂到另一台虚拟机上删掉再重建收益和风险不成比例。5.2 回收命令报文件锁定虚拟机没真正关干净现象vmkfstools -K执行后立刻返回Failed to open disk: The file is locked或类似的错误。原因最直接的原因是虚拟机没关机或者处于挂起状态。次常见的是这台虚拟机被某个备份任务挂载了——很多备份软件走的是热添加快照的方式会在 ESXi 侧短暂持有一个只读句柄这时候哪怕虚拟机是关着的文件也是锁的。第三种情况是上次回收中途被打断ESXi 侧留下了陈旧的锁记录。解决先用vim-cmd vmsvc/power.getstate vmid确认电源状态是真的 powered off别信界面上那个可能没刷新的图标。然后查有没有正在跑的备份或复制任务等它们结束。如果确认都没有还是锁着用vmfsfilelockinfo -p /vmfs/volumes/.../win2012-test.vmdk查是谁持有锁定位到具体主机和进程再处理。实在不行重启管理代理services.sh restart但这一步会影响该主机上其他虚拟机的管理连接挑时间做。5.3 迁移卡在 90% 以上大多数时候不是真卡现象Storage vMotion 进度条冲到 90 多之后长时间不动几分钟甚至十几分钟没有任何变化。原因迁移的收尾阶段做的事和前面完全不同——前面是复制数据块最后这一段是在做磁盘链切换、源端快照合并、旧文件删除。这些操作都是元数据密集型而非带宽密集型用性能图表看就是带宽掉下来了但任务没结束。另外如果虚拟机在迁移期间有大量写入增量数据需要反复同步也会让最后几个百分点拖得很久这是在线迁移的固有代价。解决先别动它。用Get-Task | Where-Object {$_.State -eq Running} | Format-List看任务状态用esxcli storage core device stats get在主机侧确认还有没有 I/O。只要任务状态是 Running 且主机没有报错等下去就是最优解。真正需要干预的情况是任务报错退出此时看 vCenter 的「近期任务」里那条红色的错误描述常见的是目标存储空间不足或源端文件被锁定这两种在对应用户手册里都有明确处理路径。5.4 清零之后磁盘反而更大别慌现象SDelete 跑到一半或者刚跑完看数据存储上的 VMDK 占用比执行前还大了几个 G。原因清零动作本身是往磁盘写数据虽然写的是零但在 VMFS 看来依然是有效的块分配。同时 Windows 在清零期间可能因为内存压力临时扩大 pagefile或者日志系统被触发写入。这些都会让占用暂时上升。只有等vmkfstools -K把这些全零块摘除之后数字才会掉下来。解决什么都不用做按流程走完回收步骤再看。真正需要警惕的是回收完成后仍然比清零前大那说明清零期间产生了新的有效数据且这些数据量超过了你回收的量这种情况要回头查这台虚拟机最近有没有异常写入——我遇到过一次是某个服务在疯狂写日志回收完一周又涨回去问题不在回收工具而在那个服务。5.5 回收效果打折碎片和分区对齐在拖后腿现象Guest 内明明删了 15G 数据回收完成后只拿回来 6G。原因Thin 的回收粒度是块级的虚拟磁盘上的块是 1MB 对齐的。如果被删除的数据在虚拟磁盘上分散成大量小块、彼此之间夹杂着有效数据那么每个 1MB 块里只要还有 1 个字节的有效数据整块就不能回收。碎片越严重回收率越低。另一个因素是分区对齐老系统上如果分区起始偏移没有按 1MB 对齐文件系统的簇边界和 VMFS 的块边界错位同一个小文件可能横跨两个 VMFS 块进一步拉低回收率。解决回收前先在 Guest 内做一次碎片整理Windows 自带的defrag C: /O对虚拟磁盘有效把有效数据尽量集中让空闲区域连成片。分区对齐的问题没法在线修只能重建分区对存量虚拟机不现实遇到这种情况就把回收率预期调到 50%70%别指望全收回。判断是否碎片导致的方法很简单跑一次defrag C: /A看分析报告里的碎片百分比超过 20% 就先整理再回收。6. 进阶把回收做成月度巡检而不是等告警了才动手手动回收这套流程跑通之后最大的问题不是技术是遗忘。Thin 磁盘的膨胀是温水煮青蛙等到数据存储告警 85% 才想起来处理往往已经被迫在业务高峰做停机操作。我现在的做法是每月初跑一次巡检把「空洞率」超过阈值的虚拟机提前筛出来在计划维护窗口里批量处理。空洞率的定义是(置备容量 - VMFS 实际占用) / 置备容量用 PowerCLI 捞一遍全环境的 Thin 虚拟机# 连接 vCenter 后执行输出空洞超过 10G 且空洞率大于 15% 的 Thin 虚拟机 $result foreach ($hd in (Get-VM | Get-HardDisk | Where-Object {$_.StorageFormat -eq Thin})) { # LayoutEx 里的 diskExtent 才是真实落在 VMFS 上的块 $extents (Get-View -Id $hd.Parent.Id).LayoutEx.File | Where-Object {$_.fileType -eq diskExtent} $onDiskGB [math]::Round((($extents | Measure-Object -Property size -Sum).Sum / 1GB), 1) $provisionedGB [math]::Round($hd.CapacityGB, 1) [pscustomobject]{ VM $hd.Parent.Name ProvisionedGB $provisionedGB OnDiskGB $onDiskGB HoleGB [math]::Round($provisionedGB - $onDiskGB, 1) HoleRate if ($provisionedGB -gt 0) { [math]::Round(($provisionedGB - $onDiskGB) / $provisionedGB * 100, 1) } else { 0 } } } $result | Where-Object {$_.HoleGB -gt 10 -and $_.HoleRate -gt 15} | Sort-Object HoleGB -Descending | Export-Csv -Path thin-reclaim-plan.csv -NoTypeInformation -Encoding UTF8这段脚本的关键在LayoutEx.File这个属性。Get-HardDisk返回的对象里CapacityGB是置备容量永远不变要找真实占用量得从虚拟机的 LayoutEx 布局信息里取fileType为diskExtent的文件项把它们的size加起来。这才是 VMFS 上真正分配掉的字节数也是和du结果对得上的那个数。多磁盘虚拟机要注意每一块盘单独算脚本里是逐块Get-HardDisk循环的输出到 CSV 后按 VM 名分组看更直观。阈值我一般定成「空洞超过 10G 且空洞率超过 15%」理由是低于这个量级回收带来的收益抵不上操作风险和停机成本。但这只是我的环境基线你们如果存储紧、窗口多可以放宽到 5G 和 10%。收回来的空间也算一笔账一台机器平均能回 812G几十台虚拟机批量跑一轮腾出半个数据存储是常事比去申请新存储走采购流程快得多。处理策略上我给这些机器分了三档。有维护窗口、存储余量紧张的走方法一安排在周末凌晨清零加回收。业务 7×24 不能停、并且有富余存储的走方法二的两跳迁移。空洞率低于 15% 但处于持续增长的先记录在案观察两个周期再决定因为这种机器往往是正常业务增长导致的回收一次很快又涨回去治标不治本。空洞率档位建议动作典型窗口 35%立即处理优先选在线迁移当周15% 35%排入月度维护窗口当月 15%只记录连续两月上升再处理观察期这套巡检跑了大半年之后我的习惯就定型了每月第一个工作日导出 CSV按空洞率排序前 10% 的机器进当月窗口其余的下月再看。有一次偷懒跳过了一个月正好赶上某台文件服务器疯狂涨盘数据存储直接顶到 92%最后不得不在周三下午做在线迁移业务虽然没断但迁移期间那台机器的响应时间翻了三倍被业务方追着问了半天。从那以后我每次做回收之前都强制先跑一遍快照检查和容量核算这两步哪怕再确定也跑因为翻车从来不是因为命令敲错而是因为状态没看全。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →