资讯动态

ESXi 升级 8.0 后 VM 快照删除不掉一直 in progress,怎么判断和修复

发布时间:2026/10/31 20:43:37 来源:尧图企业网站定制
升级完 ESXi 8.0,删除 VM 快照的时候卡在 in progress 不动。界面上没有进度条,也没有报错,就这么挂着。看了几个小时数字也没变。这里有个容易误判的地方:快照删除不是删一个文件,它是一次数据合并,可能要跑几十分钟到几小时。状态不刷新、进度条不动,看起来就像死了,但实际上 IO 可能一直在跑。删除快照实际在做什么先搞清楚流程,才知道卡在哪一步能做什么。① 准备 创建一个新的 delta 磁盘,把后续写入重定向过去 ↓ ② 合并(耗时的部分) 把原 delta 里的数据按块合并回基础 vmdk 这一步要读写基础盘的每一个块 ↓ ③ 清理 合并完成后删掉中间的 delta 文件 ↓ ④ 改元数据 更新 .vmsd,标记这个快照已删除卡住基本都发生在第 ② 步。第 ② 步如果被强行中断,第 ③、④ 步不会执行,结果就是留下孤儿 delta 磁盘,状态永远卡在 in progress。这也是为什么重启一下从来不管用。还有一个影响速度的因素:合并器要一边追赶 VM 的实时写入,一边做数据搬运。VM 越忙,合并越慢。所以高峰期点删除,可能要等很久。先判断是在干活还是卡死了这一步是整篇文章最关键的地方,判断错了越修越乱。四个检查,按顺序做,走到第三步基本就有结论了。第一,看 VM 的 IO 曲线。# vSphere Client → VM → Monitor → Performance → Disk # # 读写曲线一直在动 → 合并在跑,什么都别做,等 # 连续 10 分钟全是 0 → 真的停了,继续往下查只做这一个检查就能覆盖八成的判断需求。合并过程是 IO 密集的,datastore 上的读写流量一定会有波动。第二,看主机上有没有合并进程。# SSH 进 ESXi ps | grep -E vmkfstools # 有 vmkfstools 在跑 → 合并进行中,继续等第三,看 delta 文件大小有没有变化。这个最直接。ls -lh /vmfs/volumes/DS/VMName/VMName-000001-delta.vmdk # 记下大小,过 5 分钟再跑一次对比 # # 大小在变 → 在合并 # 完全不动 → 合并进程已经死了第四,看日志有没有合并记录。grep -i consolidat\|snapshot /var/log/vmkernel.log | tail -20 # 有 Consolidation 相关记录 → 合并启动过还在合并的话,要等多久官方的经验值是 5 到 15 GB 每分钟,取决于存储 IOPS 和 VM 的写入压力。可以粗略这么算:预计耗时(分钟) ≈ 快照数据总量(GB) ÷ 10 50 GB → 约 5 分钟 200 GB → 约 20 分钟 1 TB → 约 100 分钟 5 TB → 约 8 小时 20 TB → 约 33 小时除数可以按实际情况调:低 IOPS 存储或者高写入负载时取 5,全闪存且负载低时取 20。用 delta 文件的实际大小算比用快照创建时间准:ls -lh /vmfs/volumes/DS/VMName/VMName-000001-delta.vmdk # 假设 350GB,除以 10 就是 35 分钟等的过程中:可以做的:降低 VM 的业务负载,合并会明显加快。算一下大概还要多久,心里有数。不要做的:重启 ESXi 或 VM、对这台 VM 做 vMotion 或者 Storage vMotion、点取消删除。最后一条要特别说一下。取消删除会重新走第 ① 步,生成新的 delta 磁盘,之前的合并进度全白费。数据量大的时候,等于从头再来一遍。如果估算时间太长,不如主动干预算出要 15 小时这种,干等不如强制合并。vmkfstools 直接做合并,不追赶实时写入,通常快得多。进程没了,合并真的停了先试官方工具重新触发一次合并:# vSphere Client # 选中 VM → 右键 → Snapshots → Consolidate # PowerCLI Get-VM ProblemVM | Consolidate-VM # vim-cmd vim-cmd vmsvc/snapshot.removeall vmid如果报 File is locked,说明有进程还占着文件锁。找出是谁占的:# 列出锁信息 vmkfstools -D /vmfs/volumes/DS/VMName/*.vmdk # 输出形如: # Lock [type 10c00001 offset 4587520 v 3185, hb offset 3481600 # gen 17, mode 1, owner 65c5e4e4-1a2b-3c4d-5e6f-7a8b9c0d1e2f] # ↑ 这是 ESXi 的 MAC 地址 # # 用这个 MAC 找出是哪台 ESXi # 然后去那台主机上看 lsof | grep VMName-000001.vmdk # # 确认是残留进程后再处理 kill -9 pid杀进程这步有风险,生产环境建议先把 VM 关掉再操作。元数据坏了的情况最麻烦的一种:快照删不掉,刷新一下连快照列表都空了,但状态还是 in progress。这说明 .vmsd 元数据和实际文件对不上了。这时候只能绕过 UI 直接操作文件。这一步不可逆,做之前必须完整备份 VM 目录。# 备份 mkdir /vmfs/volumes/DS/VMName_backup cp -r /vmfs/volumes/DS/VMName/* /vmfs/volumes/DS/VMName_backup/ # 先看清快照链 ls -lh /vmfs/volumes/DS/VMName/ # 典型结构: # VMName.vmdk ← 基础盘 # VMName-000001.vmdk ← 快照 1 # VMName-000001-delta.vmdk # VMName-000002.vmdk ← 快照 2 # VMName-000002-delta.vmdk # VMName.vmsd ← 快照元数据 # VMName.vmx # 关机 vim-cmd vmsvc/power.off vmid # 强制合并 # 把最新的 delta 合并回基础盘 vmkfstools -i /vmfs/volumes/DS/VMName/VMName-000002.vmdk \ /vmfs/volumes/DS/VMName/VMName.vmdk # 这个命令会读 -000002.vmdk,合并进 VMName.vmdk, # 输出到临时文件再原子替换,过程中会打印进度 # 清理残留 rm /vmfs/volumes/DS/VMName/VMName-000001*.vmdk rm /vmfs/volumes/DS/VMName/VMName-000002*.vmdk # 改 vmx 里的磁盘指向 # 编辑 VMName.vmx: # scsi0:0.fileName VMName-000002.vmdk # 改成: # scsi0:0.fileName VMName.vmdk # 同时删掉所有 checkpoint.* 开头的行 # 以及 checkpoint.vmState # 重新注册并启动 vim-cmd solo/registervm /vmfs/volumes/DS/VMName/VMName.vmx vim-cmd vmsvc/power.on vmid几个必须注意的:VM 必须关机。运行中改 vmdk 指向会导致数据不一致。必须先备份。这些操作没有撤销功能,备份是唯一的退路。如果在别的 ESXi 上重建,记得改uuid.bios和uuid.location,不然会和原 VM 冲突。如果数据特别重要,更稳妥的做法是导出一个新 VM,而不是在原 VM 上修:# vSphere Client → 右键 VM → Export → OVF Template # 导出成干净的 OVF,再部署成新 VM # 原 VM 保持不动,确认新 VM 正常后再决定删不删原来那个 # 命令行: vim-cmd vmsvc/clone vmid /DC/vm NewCleanVM /Datastore DS怎么避免再遇到快照删不掉基本都是用得太野造成的。几条我一直在用的规矩。第一条,给快照设生命周期上限。关键业务不超过 24 小时,数据库不超过 4 小时。理由不是磁盘空间,是合并窗口——活得越久,合并时越可能撞上业务高峰,越慢。# 找出超过 7 天没清理的快照 Get-VM | Get-Snapshot | Where-Object { $_.Created -lt (Get-Date).AddDays(-7) } | Select-Object VM, Name, Created, SizeMB # 找出元数据已经有问题的快照 # Created 为空通常意味着这层元数据坏了 Get-VM | Get-Snapshot | Where-Object { -not $_.Created } | Select-Object VM, Name, Id第二条,备份用备份软件,不要拿快照顶替。VMware 自己在文档里反复强调这点。真正需要恢复点的时候用专业备份工具(Veeam、Nakivo 这类),它们自己管快照,而且合并期间能对业务限速,不会把你的 IO 打满。第三条,控制快照链层数。ESXi 硬上限是 32 层,但实际超过 5 层就该清理了。层数越多,每次合并要处理的链条越长,越容易在中间出问题。第四条,批量清理挑时间。清理本身也是 IO 密集操作,别在业务高峰跑。# 先看一遍要删什么 $ToRemove Get-VM | Get-Snapshot | Where-Object { $_.Created -lt (Get-Date).AddDays(-7) } Write-Host 即将删除 $($ToRemove.Count) 个快照: $ToRemove | Select-Object {NVM;E{$_.VM.Name}}, Name, {NDays;E{[int]((Get-Date) - $_.Created).TotalDays}} # 确认没问题再执行 # $ToRemove | Remove-Snapshot -Confirm:$false诊断脚本把前面的判断步骤串起来,只读,随时能跑:#!/bin/bash # snapshot_diag.sh # 用法:./snapshot_diag.sh # 退出码:0正在合并,1已停止需干预,2参数错误 VM_PATH$1 if [ -z $VM_PATH ] || [ ! -d $VM_PATH ]; then echo 用法:$0 echo 例如:$0 /vmfs/volumes/datastore1/VMName exit 2 fi echo echo 快照状态诊断 echo 目标:$VM_PATH echo 时间:$(date) echo # --- 1. 快照链结构 --- echo echo [1/4] 快照链结构 ls -lh $VM_PATH/*.vmdk 2/dev/null | awk {print $5 \t $9} if ls $VM_PATH/*.vmsd /dev/null 21; then echo --- .vmsd 内容 --- cat $VM_PATH/*.vmsd 2/dev/null | head -20 | sed s/^/ / fi # --- 2. 合并耗时估算 --- echo echo [2/4] 合并耗时估算 DELTA_TOTAL0 for f in $VM_PATH/*-delta.vmdk; do [ -f $f ] || continue SIZE_KB$(du -k $f | cut -f1) DELTA_TOTAL$((DELTA_TOTAL SIZE_KB)) echo $(basename $f):$((SIZE_KB/1024)) MB done if [ $DELTA_TOTAL -gt 0 ]; then TOTAL_GB$((DELTA_TOTAL/1024)) echo 合计:${TOTAL_GB} GB echo 预计耗时:约 $((TOTAL_GB/10)) 分钟(按 10GB/分钟) else echo 没有 delta 文件,可能已经合并完了 fi # --- 3. 合并进程 --- echo echo [3/4] 合并进程状态 PROCS$(ps | grep vmkfstools | grep -v grep) if [ -n $PROCS ]; then echo [进行中] 发现合并进程: echo $PROCS | sed s/^/ / echo echo ▶ 结论:合并正在进行,建议等待 exit 0 else echo [停止] 没有找到合并进程 fi # --- 4. 文件变化检测 --- echo echo [4/4] 文件变化检测(等 10 秒对比) STAT_BEFORE$(du -sk $VM_PATH/*-delta.vmdk 2/dev/null | awk {s$1} END{print s0}) sleep 10 STAT_AFTER$(du -sk $VM_PATH/*-delta.vmdk 2/dev/null | awk {s$1} END{print s0}) LOCKS$(vmkfstools -D $VM_PATH/*.vmdk 2/dev/null | grep -c Lock) echo 文件锁数量:$LOCKS LOG_HITS$(grep -ic consolidat /var/log/vmkernel.log 2/dev/null) echo vmkernel.log 中 consolidation 记录数:$LOG_HITS if [ $STAT_AFTER -ne $STAT_BEFORE ]; then echo [变化中] delta 文件还在变,合并有活动 echo ▶ 结论:建议继续等待 exit 0 fi echo echo echo ▶ 结论:合并进程已停止且文件无变化 echo echo 处理顺序: echo 1. vCenter 里试 Snapshots → Consolidate echo 2. 仍然失败用 vim-cmd vmsvc/snapshot.removeall vmid echo 3. 涉及文件级操作时,务必先备份 VM 目录 echo exit 1第四步那个两次采样对比大小是最有价值的部分。它比界面状态可靠得多,因为它直接看文件在不在动。几个容易绕远路的地方第一个,看到 in progress 就点取消。取消会重新走第 ① 步,生成新 delta,之前的进度全废,等于从头再来。第二个,合并过程中重启 ESXi。这会留下孤儿 delta 磁盘,数据没合并回去,文件也没删,状态永远卡着。这就是为什么这个故障重启从来不管用。第三个,用 rm 删 delta 文件。delta 文件是快照数据的唯一载体,删了就真丢了。想清理必须先合并。第四个,VM 运行时做文件级操作。vmkfstools 合并、改 vmx、改指向,这些都要求关机。运行中做会导致数据不一致,这种损坏比快照删不掉严重得多。第五个,忘了 RDM 磁盘的快照机制不一样。有些 RDM 配置下根本不支持快照,这种情况要先确认磁盘类型,而不是反复尝试删除。官方参考vSphere 存储文档里 snapshot 那一节讲了合并机制;KB1001993 记录了快照删除卡在 in progress 的处理流程;KB1028035 讲快照和 VM 备份配合时的注意事项。版本相关的在 VMware Environment Browser 里查。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑