本文适用版本:ESXi 7.0 U3 → 8.0 U2 升级场景(vSphere 6.7 升级也会遇到)阅读时长:约 8 分钟难度:⭐⭐⭐(操作不可逆,生产 VM 强烈建议先备份再动)一、为什么写这篇文章?最近私信里又有几位网友问:ESXi 7.0 升到 8.0 之后,VM 的快照怎么都删不掉,vSphere Client 里一直显示 Snapshot removal is in progress,挂了一整天也不动。有人直接重启 ESXi,结果快照文件不但没释放,反而多出一堆孤儿 delta 磁盘;DBA 朋友更惨——备份脚本每天对 30 台 VM 跑一致性快照,卡死后整套备份策略直接瘫痪。今天这篇文章把这个坑彻底讲清楚,保证看完你能独立判断是 等、是 主动清、还是 暴力拆。二、先搞清楚:快照删除的内部流程ESXi 删快照不是按下按钮就删完,而是一个多步骤事务:1. 创建临时 delta 磁盘(把后续写入重定向到新文件) 2. 把原 vmdk 数据合并回基础磁盘(consolidate) 3. 合并完成后删除中间的 delta 文件 4. 更新 vmx/vmsd 元数据,标记快照已删除 如果第 2 步卡住 → in progress 状态持续 如果第 2 步异常退出 → 快照异常,需要手动 consolidate关键认知:快照删除本质上是磁盘数据合并,VM 还在跑、还在写盘,合并器就要追赶实时 IO——VM IO 越大,合并越慢;VM 内存越大,内存状态合并更慢。三、3 秒定位:快照到底卡在哪一步?SSH 进 ESXi(或者 vCenter 的 ESXi shell),跑:# 1. 看快照文件实际大小(找到目标 VM 的 datastore 路径) find /vmfs/volumes/ -name *delta* -size 1G -exec ls -lh {} \; # 2. 看主机上是否有正在运行的 consolidate 任务 esxcli storage vmfs datastore list | head -5 # 然后: ps | grep -E consolidat|vmkfstools # 3. 看 VM 是否有 locked 文件 find /vmfs/volumes/ -name *.lck 2/dev/null | head -20状态对照表:现象卡在哪严重程度vSphere Client 显示 in progress 但 vmkernel.log 有合并 IO 记录第 2 步(磁盘合并中) 等就行卡了几小时,但合并进程不在 ps 里第 2 步异常退出 需要手动 consolidate快照列表里看到重复 / 出现孤儿 delta第 4 步元数据损坏 需要手动清盘VM 关机后快照立刻能删第 1 步被 VM 锁住 VM 状态问题四、第一道解法:等!(适用于 70% 的情况)官方标准:快照删除的速度大约5–15 GB/分钟,取决于存储 IOPS 和 VM 写入压力。换算公式:预计耗时(分钟) 快照数据总量(GB) ÷ 10 举例: - 50GB 快照 → 约 5 分钟 - 200GB 快照 → 约 20 分钟 - 1TB 快照 → 约 100 分钟(1.5 小时) - 5TB 快照 → 约 8 小时怎么判断是不是真的卡了:# 在 vSphere Client 里: # Monitor → Performance → Disk → 看 datastore 的 read/write 流量 # 如果 IO 一直有波动 → 合并在跑,别动它 # 如果 IO 持续为 0 → 合并已停,需要介入踩坑提醒:删除过程中绝对不要重启 ESXi 或 VM,会留下孤儿 delta 磁盘不要同时对该 VM 做 vMotion / Storage vMotion,会触发快照重建不要取消删除再重新删,会重复第 1 步,生成新 delta五、第二道解法:手动 Consolidate(适用于卡死但进程不在)如果你确认合并进程已经停了(IO 持续为 0 ps 里找不到 consolidate),用官方工具强制合并:# 在 vSphere Client 里操作(推荐): # 选中 VM → 右键 → Snapshots → Consolidate # 或者用 vim-cmd(SSH 进 ESXi 后): vim-cmd vmsvc/snapshot.removeall vmid # 或者用 vmkfstools(更底层,可看进度): vmkfstools -i /vmfs/volumes/datastore1/VMName/VMName-000001.vmdk \ /vmfs/volumes/datastore1/VMName/VMName.vmdk # 看着是把 -000001.vmdk 合并回主 vmdk如果上面报错 File is locked,说明还有进程持有文件锁:# 找锁定文件的进程 vmkfstools -D /vmfs/volumes/datastore1/VMName/*.vmdk # 输出会显示类似: # Lock [type 10c00001 offset 4587520 v 3185, hb offset 3481600 # gen 17, mode 1, owner 65c5e4e4-xxxx] # MAC 和 gen 字段 → 定位到具体 ESXi 主机 # 在对应主机上找进程 lsof | grep VMName-000001.vmdk # 杀掉该进程(生产环境慎用) kill -9 pid六、第三道解法:暴力清盘(适用于元数据损坏)走到这一步就属于手术刀操作了。必须先备份 VM 目录:# ⚠️ 第一步:整 VM 目录打包(救命稻草) mkdir /vmfs/volumes/datastore1/VMName_backup cp -r /vmfs/volumes/datastore1/VMName/* /vmfs/volumes/datastore1/VMName_backup/ # 第二步:看清楚快照链 ls -lh /vmfs/volumes/datastore1/VMName/ # 典型输出: # VMName.vmdk ← 基础磁盘 # VMName-000001.vmdk ← 快照1 # VMName-000001-delta.vmdk # VMName-000002.vmdk ← 快照2 # VMName-000002-delta.vmdk # VMName.vmx ← 配置 # VMName.vmsd ← 快照元数据方案 A:把快照合并回基础盘(最稳)# 1. 关机 VM vim-cmd vmsvc/power.off vmid # 2. 删除中间层快照文件(只留基础盘 最新的 delta) # 假设你想丢弃 -000001,保留 -000002: vmkfstools -i /vmfs/volumes/datastore1/VMName/VMName-000002.vmdk \ /vmfs/volumes/datastore1/VMName/VMName.vmdk # 3. 编辑 VMName.vmx,删除所有 checkpoint.* 行 # 删除 scsi0:0.fileName 指向 -000001.vmdk 的那行 # 改回 scsi0:0.fileName VMName.vmdk # 4. 删除残留文件 rm /vmfs/volumes/datastore1/VMName/VMName-000001*.vmdk rm /vmfs/volumes/datastore1/VMName/VMName-000002*.vmdk # 5. 重新注册 VM vim-cmd solo/registervm /vmfs/volumes/datastore1/VMName/VMName.vmx # 6. 开机测试 vim-cmd vmsvc/power.on vmid方案 B:转成新 VM(更安全,推荐生产)# 把当前快照状态导出成独立 VM # vSphere Client → 右键 VM → Export → OVF Template # 然后用 OVF 部署一个新 VM,完全不依赖原快照链 # 或者直接克隆: vim-cmd vmsvc/clone vmid /DatacenterName/vm NewVMName /DatastoreName datastore1七、防患于未然:3 个最佳实践1. 快照生命周期上限(关键)生产 VM 快照不超过 24 小时数据库 VM 快照不超过 4 小时(日志增长可能撑爆)任何 VM 快照链不超过 32 层(ESXi 硬上限)2. 备份替代快照# 真正需要恢复点时,用专业备份(VEERAM / Nakivo / 国产爱数),不要用快照 # 快照 ≠ 备份,这是 VMware 官方反复强调的3. PowerCLI 定时清理孤儿快照# 找出所有超过 7 天的快照 Get-VM | Get-Snapshot | Where-Object { $_.Created -lt (Get-Date).AddDays(-7) } | Select-Object VM, Name, Created, SizeMB | Format-Table -AutoSize # 找出所有卡死的快照(没有 Created 字段的) Get-VM | Get-Snapshot | Where-Object { -not $_.Created } | Select-Object VM, Name, Id | Format-Table -AutoSize八、速查命令卡(可收藏转发)# 1. 估算删除时间 预计耗时(分钟) 快照数据总量(GB) ÷ 10 # 2. 手动 consolidate(VM 在跑时) vim-cmd vmsvc/snapshot.removeall vmid # 3. 强制合并(VM 关机时) vmkfstools -i /vmfs/volumes/datastore1/VM/VM-000001.vmdk \ /vmfs/volumes/datastore1/VM/VM.vmdk # 4. 看谁锁住了文件 vmkfstools -D /vmfs/volumes/datastore1/VM/*.vmdk # 5. 找出孤儿快照 Get-VM | Get-Snapshot | Where-Object { -not $_.Created } # 6. PowerCLI 批量清理 7 天前的快照 Get-VM | Get-Snapshot | Where-Object { $_.Created -lt (Get-Date).AddDays(-7) } | Remove-Snapshot -Confirm:$false