摘要: 在 VMware ESXi 虚拟化运维中,“系统盘(datastore1)莫名其妙被撑爆”、“虚拟机删了文件但.vmdk只涨不缩”、“提示需要整合虚拟机磁盘却报错Device or resource busy”是最常遇到的三大存储噩梦。本文将从 ESXi 快照链的底层文件机制讲起,手把手带你完成系统盘减负、Scratch/Swap 迁移、孤立快照清理、vmkfstools离线收缩、ESXi 7.0/8.0 在线UNMAP/TRIM自动回收以及.vmdk文件锁死无损解锁的完整闭环。
目录
- 深度剖析:ESXi 默认的虚拟机快照存储逻辑
- 防患未然:6 招省下虚拟机与数据存储空间
- 宿主机减负:迁移默认 Scratch 分区与系统交换文件
- 清理积垢:排查并安全合并残留的“孤立快照”
- 空间回收实战:从
vmkfstools -K手动收缩到UNMAP/TRIM全自动回收 - 终极急救:彻底解决
.vmdk报错Device or resource busy(文件被锁定) - 附:ESXi 存储运维黄金法则速查清单
一、深度剖析:ESXi 默认的虚拟机快照存储逻辑
很多人误以为 ESXi 的虚拟机快照(Snapshot)是对整块虚拟磁盘进行完整的“复制备份”,实则不然。ESXi 快照是基于 写时重定向(Redirect-on-Write, RoW) 机制实现的增量差异记录。
默认情况下,当你对一台虚拟机拍摄快照时,所有快照相关的文件都会直接生成在该虚拟机所在的同一数据存储(Datastore)工作目录下。
1.1 快照链的核心文件组成与角色
拍摄快照瞬间,ESXi 会在虚拟机目录中操作或生成以下几类核心文件(假设虚拟机名为 vm):
| 文件名示例 | 角色名称 | 存储逻辑与空间占用特点 |
|---|---|---|
vm-flat.vmdk | 基础数据盘(Base Disk) | 存放快照前的原始数据。一旦打快照,该文件立即被锁定为只读(Read-Only)状态,体积不再变化。 |
vm.vmdk | 基础盘描述符 | 纯文本配置文件(仅几 KB),定义基础磁盘几何结构与数据块映射。 |
vm-000001-sesparse.vmdk(VMFS5 为 -delta.vmdk) | 差分数据盘(Delta Disk / 子盘) | 空间膨胀的元凶。快照创建后虚拟机所有的新写入数据都存放在这里。刚创建时接近 $0\text{ MB}$,最大可膨胀至基础盘的 $100\%$ 容量。 |
vm-000001.vmdk | 差分盘描述符 | 记录当前差分盘的 CID(内容 ID)以及父盘的 parentCID,靠指针串联起整条快照链。 |
vm-Snapshot1.vmsn | 快照状态与内存文件 | 若未勾选内存快照,仅几十 KB(存虚拟 BIOS/设备状态);若勾选了“拍摄虚拟机内存快照”,其体积直接等于虚拟机配置的内存大小(如 $16\text{ GB}$ 内存就立刻占 $16\text{ GB}$)。 |
vm.vmsd | 快照关系数据库 | 纯文本字典文件,记录快照管理器中看到的快照名称、创建时间及树状父子关系。 |
1.2 读写、恢复与删除(合并)的底层运作
[初始无快照状态]
VM 读写 I/O ───────────────────────────> [ vm-flat.vmdk (读写) ]
[创建快照 1 + 快照 2 后的链式状态]
VM 新写入 I/O ─────────────────────────> [ vm-000002-sesparse.vmdk (活动读写) ]
│ (parentCID 回退查读)
▼
[ vm-000001-sesparse.vmdk (冻结只读) ]
│ (parentCID 回退查读)
▼
[ vm-flat.vmdk (冻结只读) ]- 写入逻辑(只写最新差分盘):
拍摄快照 1 后,基础盘vm-flat.vmdk被冻结为只读;ESXi 新建子盘vm-000001-sesparse.vmdk。此后虚拟机内部修改或新增的任何数据块,都会直接写入这个000001差分盘。如果你再拍一个快照 2,000001也会变为只读,系统再建000002差分盘承接写入。每一层差分盘理论最大均可膨胀至基础盘 $100\%$ 的容量! 读取逻辑(自下而上逐层穿透):
当虚拟机需要读取某个磁盘扇区时,ESXi 会先去最新的差分盘(如000002)里找:- 如果该扇区在快照 2 之后被修改过,直接从
000002返回数据; - 如果未修改,顺着
parentCID指针往上查000001; - 如果还没修改,最终回到最底层的
vm-flat.vmdk读取原始数据。这也是为什么快照层数越多,磁盘 I/O 性能下降越剧烈。
- 如果该扇区在快照 2 之后被修改过,直接从
- 恢复快照(Revert / 转到):
丢弃当前活动差分盘中的所有更改,将磁盘指针重新指回目标快照节点,并基于该节点派生出一个新的空白差分盘继续运行。 删除快照(Delete / 合并整合):
这是最容易让人误解的操作——在快照管理器里点击“删除(Delete)”,并不是丢弃快照期间产生的数据,而是将差分盘的数据向下合并(Consolidate)到父盘或基础盘中,以保留虚拟机当前的最新状态,合并完成后再删掉差分文件。⚠️ 空间陷阱: 如果你有多层快照(如基础盘 $\rightarrow$ 快照 1 $\rightarrow$ 快照 2),在删除中间层快照或虚拟机高负载写入时执行合并,整合过程可能会在磁盘上产生额外的临时空间开销,极端情况下会瞬间塞满剩余空间导致虚拟机挂起。
二、防患未然:6 招省下虚拟机与数据存储空间
按空间节省效果从大到小排列,日常运维中可通过以下 6 项措施大幅降低快照与衍生文件对系统盘的消耗:
2.1 拍摄快照时取消勾选“拍摄虚拟机内存快照”(立省数 GB 至数十 GB)
在 Web Client 中创建快照时,默认往往勾选了 “拍摄虚拟机内存快照(Snapshot the virtual machine's memory)”。
- 为什么费空间: 勾选后,ESXi 会把虚拟机当前内存里的所有数据完整转储成
.vmsn文件。一台 $32\text{ GB}$ 内存的虚拟机拍 2 个带内存的快照,什么都没干就会先白白吃掉 $64\text{ GB}$ 硬盘空间。 - 最佳实践: 拍摄时取消勾选该选项。虽然恢复快照时虚拟机会像重启一样重新开机(而不是直接回到运行桌面),但
.vmsn文件会从几十 GB 骤降到几 MB,且拍快照的速度从几分钟缩短到 1 秒钟。
2.2 修改 workingDir,将快照文件重定向到大容量数据盘
如果你的 ESXi 安装在一块较小的 SSD 系统盘上(虚拟机也放在上面),而机器上还挂载了另一块大容量机械盘或 NAS 存储,你可以让虚拟机本体留在 SSD 上享受高 IOPS,但把快照(-delta/-sesparse、.vmsn)全部重定向到大容量数据盘。
配置步骤:
- 关闭虚拟机电源。
- 右键虚拟机 $\rightarrow$ 编辑设置(Edit Settings) $\rightarrow$ 虚拟机选项(VM Options) $\rightarrow$ 高级(Advanced) $\rightarrow$ 编辑配置(Edit Configuration)。
- 点击添加参数,键名填
workingDir,键值填目标数据存储的路径,例如:/vmfs/volumes/大容量存储名称或UUID/Snapshots_Folder/ - 保存并开机。此后该虚拟机的所有快照和挂起文件都会生成在新的存储上,完全不占原系统盘空间。
2.3 将临时盘、页面文件盘或日志盘设为“独立磁盘(Independent Disk)”
虚拟机内部经常有大量高频但无备份价值的数据写入,例如 Windows 的虚拟内存页面文件(pagefile.sys)、Linux 的 swap 分区、临时缓存目录(/tmp)或高吞吐日志盘。如果在快照期间这些数据放在普通磁盘上,每一次交换写入都会导致 -sesparse.vmdk 差分盘飞速膨胀。
省空间方案:
- 给虚拟机单独添加一块小容量的虚拟硬盘,专门用来放系统的
pagefile.sys、临时文件或缓存。 - 在虚拟机设置中展开该硬盘,将磁盘模式(Disk Mode)修改为 独立 - 持久(Independent - Persistent)。
- 效果: 设为“独立”模式的虚拟磁盘完全不参与虚拟机快照。打快照时只有系统盘会生成差分文件,独立盘正常直接读写,不会产生任何增量快照体积。(注:挂载了独立磁盘的虚拟机若要在线拍快照,必须取消勾选“拍摄内存快照”)。
- 给虚拟机单独添加一块小容量的虚拟硬盘,专门用来放系统的
2.4 通过设置“内存预留”彻底消除 .vswp 交换文件
除了快照,虚拟机开机时默认还会在系统盘目录下生成一个与内存等大的 .vswp 交换文件(例如分配 $16\text{ GB}$ 内存,开机就占走 $16\text{ GB}$ 磁盘空间)。其体积计算公式为:
$$\text{Size}_{\text{.vswp}} = \text{RAM}_{\text{配置内存}} - \text{RAM}_{\text{已预留内存 (Memory Reservation)}}$$
- 省空间方案: 如果宿主机物理内存充足,进入虚拟机 编辑设置 $\rightarrow$ 虚拟硬件 $\rightarrow$ 内存 $\rightarrow$ 预留(Reservation),勾选“预留所有客户机内存(全部锁定)”或调高预留值。预留 $100\%$ 内存后,该虚拟机开机时的
.vswp文件占用将直接变为 $0\text{ MB}$。
2.5 快照期间严禁在虚拟机内执行“全盘写”操作
因为 ESXi 快照是基于数据块(Block-level)的写时重定向,哪怕你在虚拟机里新建了一个 $50\text{ GB}$ 的文件又立刻把它删掉,差分盘也会永久膨胀 $50\text{ GB}$(直到删除合并快照才会释放)。
避坑准则:
- 带着快照时,绝对禁止在虚拟机内部运行传统磁盘碎片整理(Defrag),否则整块磁盘的数据块发生位移,差分盘会瞬间膨胀到基础盘的 $100\%$ 大小。
- 打快照后尽量在 $24\sim 72$ 小时内验证完业务并点击“删除(合并)”快照,避免快照链超过 3 层。
2.6 确保使用 VMFS6 + 精简置备(Thin Provisioning)
在 ESXi 6.5 及更高版本(VMFS6 数据存储) 中,默认快照格式已从传统的 VMFSsparse(-delta.vmdk)全面升级为 SEsparse(-sesparse.vmdk)。将基础磁盘设为精简置备(Thin Provision),配合客户机内部的 TRIM / UNMAP 指令,可在删除文件后自动回收空闲数据块。
三、宿主机减负:迁移默认 Scratch 分区与系统交换文件
ESXi 宿主机除了存放虚拟机文件外,默认还会在引导盘或首个数据存储(datastore1)上创建 Scratch 暂存目录(.locker) 和 系统交换文件(System Swap)。将这两项迁移到大容量数据盘或 NAS 存储上,通常能立即为系统盘腾出 $4\text{ GB}\sim\text{数十 GB}$ 的可用空间,并大幅降低引导盘的日志写入磨损。
3.1 迁移 Scratch 暂存分区(需严格按顺序执行)
Scratch 分区用于存放系统日志(syslog)、vm-support 诊断包、VMware Tools 镜像以及崩溃转储缓存。
⚠️ 注意: 迁移时必须遵循 “先建目录 $\rightarrow$ 再改配置 $\rightarrow$ 最后重启” 的顺序——如果目标目录不存在就直接修改参数,ESXi 重启后会挂载失败并被迫回退到内存盘(/tmp/scratch)。步骤 1:在目标数据存储上新建专属暂存目录
- 登录 ESXi Web Client,进入 存储(Storage) $\rightarrow$ 数据存储(Datastores)。
- 点击你要迁移过去的目标大容量数据存储,打开 数据存储浏览器(Datastore browser)。
- 点击 创建目录(Create directory),创建一个隐藏文件夹(推荐命名为
.locker-主机名,例如.locker-esxi01)。 - 关闭浏览器,在当前数据存储详情页复制其 位置(Location) 路径(格式如
/vmfs/volumes/5f8a...-uuid...或/vmfs/volumes/目标存储名称)。
步骤 2:修改 ScratchConfig 系统高级参数
方式 A(Web 界面):
- 进入 管理(Manage) $\rightarrow$ 系统(System) $\rightarrow$ 高级设置(Advanced settings)。
- 搜索
ScratchConfig,找到ScratchConfig.ConfiguredScratchLocation,点击 编辑选项。 - 填入刚才创建的完整目录路径(如
/vmfs/volumes/MyBigDisk/.locker-esxi01),点击保存。
方式 B(SSH 命令行一键修改):
# 1. 创建目标目录(将 MyBigDisk 替换为你的目标数据存储名称) mkdir -p /vmfs/volumes/MyBigDisk/.locker-esxi01 # 2. 指定新的 Scratch 路径 vim-cmd hostsvc/advopt/update ScratchConfig.ConfiguredScratchLocation string /vmfs/volumes/MyBigDisk/.locker-esxi01
步骤 3:重启宿主机并清理旧目录
- 关闭宿主机上的虚拟机,右键主机选择 进入维护模式,随后点击 重新引导(Reboot)。
- 重启完成后,回到 高级设置 搜索
ScratchConfig,确认ScratchConfig.CurrentScratchLocation已变成新路径。 - 打开原系统盘(
datastore1)的数据存储浏览器,选中残留的旧.locker文件夹并彻底删除(或通过 SSH 执行rm -rf /vmfs/volumes/datastore1/.locker)。
3.2 更改系统交换文件(System Swap)位置(无需重启,立即生效)
- 在单机版 ESXi Host Client 中修改:
依次进入 管理(Manage) $\rightarrow$ 系统(System) $\rightarrow$ 交换(Swap) $\rightarrow$ 点击 编辑设置 $\rightarrow$ 在 数据存储 下拉菜单中切换为大容量数据存储 $\rightarrow$ 点击 保存。 在 vCenter Server(vSphere Client)中同时重定向宿主机与虚拟机交换:
- 宿主机系统交换: 选中主机 $\rightarrow$ 配置 $\rightarrow$ 系统 $\rightarrow$ 系统交换 $\rightarrow$ 编辑并指向大容量盘。
- 虚拟机默认
.vswp位置: 选中主机 $\rightarrow$ 配置 $\rightarrow$ 虚拟机 $\rightarrow$ 交换文件位置 $\rightarrow$ 选择“将交换文件存储在主机指定的数据存储中”并指向大容量盘。
通过 SSH 命令行快速修改:
# 查看当前系统交换配置状态 esxcli sched swap system get # 将系统交换位置切换至指定的数据存储(替换 MyBigDisk 为实际数据存储名) esxcli sched swap system set --datastore-enabled=true --datastore-name="MyBigDisk"
3.3 补充避坑:ESXi 7.0 / 8.0 系统盘被 OSData 吃掉 120GB 怎么办?
在 ESXi 7.0 及 8.0 中,VMware 引入了包含 Scratch、日志和系统状态在内的 ESX-OSData 分区。如果在 $128\text{ GB}$ 或 $256\text{ GB}$ 的 SSD 上默认安装 ESXi 7/8,安装程序会在 GPT 分区表层面直接划走高达 $120\text{ GB}$ 给 OSData。
- 如果
.locker位于datastore1内,按上述步骤迁移后空间会直接归还给datastore1。 - 如果 Scratch 位于独立的 $120\text{ GB}$
OSData分区,迁移 Scratch 可停止对引导盘的写入磨损,但不会自动缩小 GPT 分区。若想在重装时彻底把这 $100\text{ GB}+$ 空间留给datastore1,需在安装引导界面按Shift + O,追加启动参数systemMediaSize=small(仅占 $32\text{ GB}$)或systemMediaSize=min(仅占 $24\text{ GB}$)。
四、清理积垢:排查并安全合并残留的“孤立快照”
当 Web 界面弹出黄色警告 “需要整合虚拟机磁盘(Virtual machine disks consolidation is needed)”,或者“快照管理器”里空空如也,但数据存储目录里却躺着一堆 vm-000001.vmdk、vm-000002.vmdk 时,说明发生了快照元数据(.vmsd)与底层差分文件脱节(常见于第三方备份软件如 Veeam、群晖 ABB 临时快照解锁超时,或删除大快照时空间不足中断)。
🛑 安全底线: 绝不能在文件浏览器里直接手动删除 -00000X.vmdk 文件!4.1 第一步:通过 SSH 精准排查当前挂载关系
登录 ESXi SSH,进入该虚拟机目录,先摸清虚拟机当前到底在读写哪个文件:
# 1. 进入虚拟机目录
cd /vmfs/volumes/datastore1/你的虚拟机名称/
# 2. 查看虚拟机配置文件当前挂载的是哪块磁盘(最关键!)
grep -i ".vmdk" *.vmx- 判断依据: 如果输出显示
scsi0:0.fileName = "vm-000002.vmdk",说明虚拟机此时此刻正在把所有新数据写进000002这个差分盘里。若直接删掉000002.vmdk或000001.vmdk,虚拟机将立刻崩溃且丢失快照以来的全部增量数据!
4.2 第二步:四种安全清理与合并方案(按优先级由浅入深)
| 方案场景 | 具体操作步骤 | 适用情况 |
|---|---|---|
| 方案 A:直接触发整合 (首选,在线无损) | 右键点击虚拟机 $\rightarrow$ 快照(Snapshots) $\rightarrow$ 整合磁盘(Consolidate Disks),确认执行并等待任务进度条走完。 | 界面明确提示“需要整合虚拟机磁盘”,且数据存储剩余空间充足。 |
| 方案 B:“新建再全删”重置法 (解决快照管理器空白但有残留文件) | 1. 右键虚拟机 $\rightarrow$ 拍摄快照(务必取消勾选“拍摄内存快照”)。 2. 拍完后打开 管理快照 $\rightarrow$ 点击“删除全部(Delete All)”。 | 快照管理器里看不到任何快照,“整合”按钮也是灰色的,但目录里仍有 -00000X.vmdk。这会强制 ESXi 重新扫描整条父子链并一次性合并到底层基础盘。 |
| 方案 C:SSH 命令行强制整合 (绕过 Web UI 假死或按钮置灰) | 1. 获取虚拟机 ID:vim-cmd vmsvc/getallvms2. 查看快照状态: vim-cmd vmsvc/snapshot.get 虚拟机ID3. 强制移除并合并所有快照: vim-cmd vmsvc/snapshot.removeall 虚拟机ID | 单机版 ESXi Host Client 网页界面响应异常、按钮置灰无法点击。 |
方案 D:vmkfstools -i 跨盘克隆合并(终极救砖:解决原盘空间满无法就地合并) | 1. 关闭虚拟机电源。 2. 将当前最新的差分盘克隆到另一块有空间的硬盘或目录: vmkfstools -i vm-000002.vmdk /vmfs/volumes/其他存储/new_vm/vm.vmdk -d thin3. 编辑虚拟机设置,移除旧硬盘,挂载新克隆出来的 vm.vmdk,确认开机正常后删除旧盘文件。 | 原系统盘剩余空间已不足以支撑就地合并(例如只剩几百 MB),或者快照链锁死报错。vmkfstools -i 会自动顺着差分链读取所有有效数据并合成为一个全新的无快照单文件磁盘。 |
五、空间回收实战:从 vmkfstools -K 手动收缩到 UNMAP/TRIM 全自动回收
当你在虚拟机里面删掉了 $100\text{ GB}$ 的无用文件,操作系统只是在文件目录表里把这片区域标记为“可覆盖”,磁盘扇区底层的二进制数据依然残留着(非零数据块)。若不经处理,ESXi 无法感知这些块已空闲,导致精简置备(Thin)磁盘“只涨不缩”。
下面提供两种回收方案:离线手动彻底收缩法(兼容所有版本) 与 ESXi 7.0/8.0 在线全自动 UNMAP/TRIM 回收法。
5.1 方案一:离线使用 vmkfstools -K 手动打孔回收(兼容所有环境)
ESXi 的 vmkfstools -K(--punchzero)只能识别并回收全部由 0 组成的数据块(Zeroed Blocks)。因此必须分两步走:先在虚拟机内部把空闲空间写零 $\rightarrow$ 再在 ESXi 宿主机上打孔回收。
阶段 1:在虚拟机内部将空闲空间“清零(Zero Out)”
⚠️ 膨胀预警: “写零”操作会创建一个全零大文件把空闲空间塞满再删掉,期间精简置备磁盘会暂时膨胀!请确保 ESXi 数据存储的剩余物理空间充足;若空间紧张,请采用分批写入法。
Linux 虚拟机:
# 方式 1:存储剩余空间充足时,直接填满空闲区后立即删除 dd if=/dev/zero of=/zero.fill bs=16M status=progress ; sync ; rm -f /zero.fill # 方式 2(安全分批法):存储剩余空间不多时,每次只写 20GB 的零,分批回收 dd if=/dev/zero of=/zero.fill bs=1G count=20 status=progress ; sync ; rm -f /zero.fillWindows 虚拟机:
下载微软官方 Sysinternals 工具包中的SDelete,以管理员身份运行 CMD 执行-z(清零空闲空间):sdelete64.exe -z C:
阶段 2:在 ESXi 宿主机上执行 vmkfstools -K 回收空间
满足三大前提:虚拟机彻底关机、无任何残留快照、磁盘为精简置备(或厚置备延迟置零)。
# 1. 进入虚拟机所在的存储目录
cd /vmfs/volumes/datastore1/你的虚拟机名称/
# 2. 查看回收前的【真实物理占用】(切勿用 ls -lh,必须用 du -h!)
du -h *-flat.vmdk
# 3. 执行打孔回收(注意:对象是不带 -flat 的那个几 KB 描述符文件!)
vmkfstools -K 你的虚拟机名称.vmdk
# 4. 等待 100% done 后,再次查看真实物理占用
du -h *-flat.vmdk5.2 方案二:在 ESXi 7.0 / 8.0 中开启 UNMAP / TRIM 在线自动空间回收(一劳永逸)
在 ESXi 7.0 / 8.0(基于 VMFS-6)中,只要打通客户机与宿主机的 UNMAP / TRIM 链路,虚拟机里删除文件后,.vmdk 即可在后台在线自动收缩,彻底省去关机跑 vmkfstools -K 的麻烦。
1. 核对 4 项硬性前提
| 检查项 | 必须满足的条件 | 不满足时的修正方法 |
|---|---|---|
| 数据存储格式 | VMFS-6(ESXi 6.7/7.0/8.0 默认) | 若为旧版升级保留的 VMFS-5,需新建 VMFS-6 存储并迁移虚拟机。 |
| 虚拟硬件版本 | $\ge$ 版本 13(兼容 ESXi 6.5+) | 最常见失效原因! 若为旧版虚拟机(版本 8~11),关机后右键虚拟机 $\rightarrow$ 兼容性 $\rightarrow$ 升级虚拟机兼容性。 |
| 虚拟磁盘控制器 | VMware Paravirtual(PVSCSI)、LSI Logic SAS 或 NVMe | 避免使用老旧的 IDE 或 BusLogic Parallel 控制器。 |
| 磁盘格式与快照 | 精简置备(Thin) 且 当前无快照 | 存在快照时基础盘只读,无法对底层 *-flat.vmdk 执行块回收。 |
2. 在 ESXi 宿主机上开启块回收开关(在线生效)
# 1. 开启宿主机全局客户机块删除支持(0 为关闭,1 为开启)
esxcli system settings advanced set -i 1 -o /VMFS3/EnableBlockDelete
esxcli system settings advanced list -o /VMFS3/EnableBlockDelete
# 2. 确认数据存储(如 datastore1)开启了自动空间回收(默认 low 为每秒回收 100MB)
esxcli storage vmfs reclaim config get -l datastore1
esxcli storage vmfs reclaim config set -l datastore1 -p low3. 在 Linux 虚拟机内部配置自动回收
# 1. 验证底层是否已打通 UNMAP 通道(查看 DISC-GRAN 和 DISC-MAX 是否为非 0B)
lsblk -D
# 2. 手动触发一次全分区在线回收(立竿见影,跑完去 ESXi 看 du -h 立即缩小!)
sudo fstrim -av
# 3. 开启 systemd 每周定时自动回收服务(生产环境最推荐,避免挂载 discard 拖慢日常 I/O)
sudo systemctl enable --now fstrim.timer
systemctl list-timers *fstrim*4. 在 Windows 虚拟机内部配置自动回收
以管理员身份打开 PowerShell:
# 1. 检查 TRIM 是否开启(返回 DisableDeleteNotify = 0 即为已开启)
fsutil behavior query DisableDeleteNotify
# 若返回 1,执行以下命令开启实时回收:
fsutil behavior set DisableDeleteNotify 0
# 2. 对历史已删除文件执行一次全盘在线 ReTrim 回收(耗时仅数秒,无需关机)
Optimize-Volume -DriveLetter C -ReTrim -Verbose六、终极急救:彻底解决 .vmdk 报错 Device or resource busy(文件被锁定)
在合并快照或操作虚拟磁盘时若遇到 Device or resource busy,说明 VMFS 文件系统的分布式锁机制检测到某个宿主机进程或另一台虚拟机正在占用该文件。切勿盲目重启整台物理宿主机,按以下 4 步即可精准无损解锁:
步骤 1:使用 vmfsfilelockinfo 查明锁持有者
通过 SSH 进入虚拟机目录,检查底层数据实体文件(锁永远加在 -flat.vmdk 或 -sesparse.vmdk 上,而非描述符文件):
cd /vmfs/volumes/datastore1/你的虚拟机名称/
vmfsfilelockinfo -p 你的虚拟机名称-flat.vmdk
vmfsfilelockinfo -p 你的虚拟机名称-000001-sesparse.vmdkFile is not locked:该文件未被锁定,继续检查同目录下的其他文件。Lock [type 10c00001 ... mode 1]:mode 1代表独占写锁。查看Owner字符串的最后 12 位(即持有锁的 ESXi 主机vmk0MAC 地址)或 IP 提示。
步骤 2:优先排查“热添加(HotAdd)”残留挂载(80% 锁死元凶)
无代理备份软件(如 Veeam、群晖 ABB、Nakivo)在备份时会把目标虚拟机的 .vmdk 临时挂载(HotAdd)到备份代理虚拟机上。一旦备份异常中断,磁盘就会一直挂在备份机上导致原机无法合并快照。
执行全局搜索,排查是否有其他虚拟机的 .vmx 正在引用该硬盘:
grep -rn "被锁定的虚拟机名称" /vmfs/volumes/*/*/*.vmx- 解锁方法: 若发现某台备份代理虚拟机在引用它,在 Web 界面右键该备份虚拟机 $\rightarrow$ 编辑设置 $\rightarrow$ 找到被挂载过来的额外硬盘点击
X移除(生死红线:移除时绝对不要勾选“从数据存储中删除文件”!)$\rightarrow$ 点击保存,锁瞬间解除。
步骤 3:通过 lsof 在当前宿主机揪出持有锁的底层进程
若确认没有被其他虚拟机挂载,执行 lsof 过滤出占用该文件的进程:
lsof | grep -i "你的虚拟机名称"观察输出的第 1 列(Cartel ID / 进程组 ID)和第 2 列(进程名称)。
步骤 4:对照进程类型分级执行无损解锁
| 锁定原因分类 | vmfsfilelockinfo / lsof 特征表现 | 安全解锁操作命令 | 是否影响同机其他 VM |
|---|---|---|---|
| 备份代理未卸载磁盘 (HotAdd 残留) | lsof 显示另一个备份虚拟机的 vmx 进程正在占用你的 -flat.vmdk | 编辑备份虚拟机的设置 $\rightarrow$ 移除该硬盘(不勾选从存储删除文件) $\rightarrow$ 保存 | 完全不影响 |
| 管理服务句柄卡死 (整合快照中途超时) | lsof 第 2 列显示为 hostd-worker 或 vpxa-worker | 执行:/etc/init.d/hostd restart/etc/init.d/vpxa restart | 完全不影响(Web 界面仅短暂重连 10 秒) |
| 虚拟机僵尸进程残留 (关机卡死或崩溃) | lsof 第 2 列显示为目标虚拟机自身的 vmx 进程 | 1. 查 World ID:esxcli vm process list2. 强杀: esxcli vm process kill --type=force --world-id=xxx(若列表无显示则执行 kill -9 <Cartel_ID>) | 仅终止该故障 VM,不影响其他 VM |
| 集群内其他主机锁死 (SAN / iSCSI 共享存储) | vmfsfilelockinfo 显示的 Owner MAC 地址属于集群内另一台 ESXi 主机 | SSH 登录到持有该 MAC 地址的那台 ESXi 主机,执行上述 lsof 与解锁步骤 | 完全不影响 |
解锁完成后,再次运行 vmfsfilelockinfo -p 你的虚拟机名称-flat.vmdk,确认输出变为 File is not locked,即可正常执行快照整合或 vmkfstools -K 回收空间。
七、附:ESXi 存储运维黄金法则速查清单
- 拍快照不拍内存: 除非调试内存状态,日常拍快照一律取消勾选“拍摄虚拟机内存快照”,省下数十 GB
.vmsn空间。 - 快照存活不超 72 小时: 快照绝非完整备份,层数控制在 3 层以内,验证完立刻点击“删除(合并)”。
- 查真实体积用
du -h: 在 ESXi SSH 中查看精简置备磁盘的实际物理占用,永远用du -h *-flat.vmdk,不要看ls -lh(后者显示的是逻辑上限)。 操作命令认准描述符与数据盘:
vmkfstools -K(打孔回收)和vmkfstools -i(克隆)指向不带-flat的描述符文件(vm.vmdk)。vmfsfilelockinfo -p(查文件锁)和du -h(查大小)指向带-flat或-sesparse的数据实体文件。
- 新装 ESXi 7/8 小容量引导盘必加参数: 在小于 $256\text{ GB}$ 的引导盘上安装 ESXi 7.0/8.0 时,启动时按
Shift + O加上systemMediaSize=small,防止OSData独占 $120\text{ GB}$。
版权属于:soarli
本文链接:https://blog.soarli.top/archives/1229.html
转载时须注明出处及本声明。