文档目录

问题说明

本文用于排查删除单盘快照、批量删除单盘快照或删除快照组时,任务在固定时间后失败,并显示 live merging snapshot chain failed, block job not finished 的问题。排查重点是先识别实际调用的删除入口,再核对对应的 API 超时配置和同一次任务的 deadline,最后判断底层 block job 是被期限取消,还是本身存在存储、容量或快照链异常。

现象

  • 已把 APIDeleteVolumeSnapshotMsg 和 APIBatchDeleteVolumeSnapshotMsg 调整为 24 小时,但删除快照仍在约 3 小时后失败。
  • 管理节点日志出现 VolumeSnapshotTreeBase$35、batch delete volume snapshot error 或 live merging snapshot chain failed, block job not finished。
  • 删除快照组时,任务详情中的外层 DeleteVolumeSnapshotGroupAction 可能显示成功,但某个成员的 results[].success 为 false,随后显示运行时错误。
  • 已记录案例中,实际请求是 APIDeleteVolumeSnapshotGroupMsg。请求携带 timeout=10800000,即 3 小时;期限到达时,在线 full rebase 的 Pull block job 仍在推进,随后被取消。

适用环境

  • 产品:ZVF ZSphere
  • 版本:4.10.25.65(已记录案例;其它版本应先按本文查询实际配置,不直接套用该版本结论)
  • 组件:单盘快照、快照组、管理节点 API timeout、KVM Agent 和 libvirt block job
  • 部署形态:删除运行中虚拟机的快照时需要在线合并快照链;已记录案例使用 SharedBlock 数据存储

可能原因

该现象可能由以下一种或多种原因导致:

  • 调整的配置项与实际操作入口不一致。例如,现场执行的是“删除快照组”,但只调整了单盘和批量单盘删除的 API timeout。
  • 配置在任务创建后才调整。一个已经开始的请求,其 deadline 已经确定;事后修改 GlobalConfig 不会延长旧任务。
  • timeout 已正确延长,但底层 block job 进度缓慢或停止推进。可能需要继续检查存储 I/O、iSCSI 路径、数据存储容量、快照链或 QEMU/libvirt 状态。
  • 只看了快照组事件的外层 success,没有检查每个成员的 results[],因而遗漏了单个卷的删除失败。

以下错误不能直接当成根因或配置名:

  • VolumeSnapshotTreeBase$35 是上层流程报告错误的位置,不是 GlobalConfig 名称。
  • disk vda does not have an active block job 如果出现在 deadline 到达、任务取消之后,通常是清理阶段再次取消 block job 的次生信息;应先找到它之前的超时和合并进度日志。

排查步骤

1. 判断删除的是单盘快照、批量单盘快照还是快照组

  • 检查对象:任务详情中的操作名称、API ID、快照 UUID、快照组 UUID、虚拟机 UUID和开始时间。
  • 操作位置:在 ZSphere UI 打开失败任务详情,记录完整错误、开始和结束时间以及 apiId。然后按实际操作对照下表:
用户操作管理节点日志中的 API对应的 API timeout GlobalConfig name
删除一个单盘快照APIDeleteVolumeSnapshotMsgorg.zstack.header.storage.snapshot.APIDeleteVolumeSnapshotMsg
一次批量删除多个单盘快照APIBatchDeleteVolumeSnapshotMsgorg.zstack.header.storage.snapshot.APIBatchDeleteVolumeSnapshotMsg
删除快照组APIDeleteVolumeSnapshotGroupMsgorg.zstack.header.storage.snapshot.group.APIDeleteVolumeSnapshotGroupMsg
  • 预期结果:任务详情和管理节点日志能够确定同一次失败请求使用了哪一个 API。
  • 异常处理:如果只看到 VolumeSnapshotTreeBase$35 或页面上的“删除快照”,不能据此选择配置项;继续执行步骤 2,从管理节点日志确认真实 API。

2. 使用 apiId 查询管理节点请求、timeout 和 deadline

  • 检查对象:同一次请求的 API 类名、timeout、deadline、内部消息和目标 ZSphere 主机。
  • 操作位置:SSH 登录管理节点,使用步骤 1 记录的 apiId 查询当前和归档日志。把引号中的示例值替换为现场值:
  KB_API_UUID='将任务详情中的apiId粘贴到这里'
  cd /usr/local/zstack/apache-tomcat/logs || exit 1
  ls -lh management-server.log*
  zgrep -a -n -C 5 "$KB_API_UUID" management-server.log*
  zgrep -a -n "$KB_API_UUID" management-server.log* | grep -iE 'APIDeleteVolumeSnapshot(Group)?Msg|APIBatchDeleteVolumeSnapshotMsg|DeleteVolumeSnapshotMsg|MergeVolumeSnapshotOnKvmMsg|timeout|deadline|mergesnapshot|block job|error'
  • 预期结果:
  • 单盘或批量单盘删除应命中各自的 API;快照组删除应命中 APIDeleteVolumeSnapshotGroupMsg。
  • 如果已按 24 小时创建新请求,应看到 86400000 毫秒及与请求时间匹配的新 deadline。
  • 内部 DeleteVolumeSnapshotMsg、MergeVolumeSnapshotOnKvmMsg 和发往 KVM Agent 的 /vm/volume/mergesnapshot 请求应属于同一条调用链,剩余期限应与上层请求一致。
  • 异常处理:
  • 如果真实入口是快照组,而日志仍显示 10800000 毫秒或约 3 小时 deadline,说明调整错了配置项,进入步骤 3。
  • 如果真实入口和 timeout 均正确,但 deadline 仍是旧值,确认该任务是否在修改配置前已经开始;旧任务不能通过事后修改配置获得新期限。
  • 如果无法从 apiId 找到 Agent taskUuid,改用快照 UUID、快照组 UUID、虚拟机 UUID和准确时间窗继续查询,并保存所有命中行。

3. 在 CLI 中查询三个删除入口的当前配置

  • 检查对象:三种删除入口的实际 GlobalConfig 值。不同版本或环境可能不同,必须查询后再决定是否调整。
  • 操作位置:SSH 登录管理节点,进入 zstack-cli 并使用有权限的账号登录,然后分别执行:
  QueryGlobalConfig category=apiTimeout name=org.zstack.header.storage.snapshot.APIDeleteVolumeSnapshotMsg
  QueryGlobalConfig category=apiTimeout name=org.zstack.header.storage.snapshot.APIBatchDeleteVolumeSnapshotMsg
  QueryGlobalConfig category=apiTimeout name=org.zstack.header.storage.snapshot.group.APIDeleteVolumeSnapshotGroupMsg
  • 预期结果:步骤 1 确认的真实 API,其配置值能够覆盖预期的删除和合并时间;同时把三个原值保存到工单中。
  • 异常处理:不要因为报错位置包含 VolumeSnapshotTreeBase$35 就查询同名配置。不要一次性盲目修改三个配置;只处理与实际入口对应的项目,并继续检查底层任务是否健康。

4. 查询 KVM Agent 和 libvirt block job 是否仍在推进

  • 检查对象:Agent taskUuid、虚拟机状态、目标盘、block job 进度和快照链 backing 信息。
  • 操作位置:先从步骤 2 的管理节点日志取得目标 ZSphere 主机、Agent taskUuid 和虚拟机 UUID,再 SSH 登录该 ZSphere 主机执行。先根据 virsh domblklist 的结果确认故障硬盘对应的目标盘符;下面用 vda 举例,现场不一致时必须替换:
  KB_TASK_UUID='将management-server日志中的taskUuid粘贴到这里'
  KB_VM_UUID='将受影响虚拟机UUID粘贴到这里'
  KB_DISK_TARGET='vda'
  cd /var/log/zstack || exit 1
  ls -lh zstack-kvmagent.log*
  zgrep -a -n -C 5 "$KB_TASK_UUID" zstack-kvmagent.log*
  zgrep -a -n "$KB_TASK_UUID" zstack-kvmagent.log* | grep -iE 'mergesnapshot|fullRebase|block|progress|timeout|deadline|cancel|error|fail'
  virsh domstate "$KB_VM_UUID"
  virsh domblklist "$KB_VM_UUID" --details
  virsh blockjob "$KB_VM_UUID" "$KB_DISK_TARGET" --info
  virsh qemu-monitor-command "$KB_VM_UUID" --pretty '{"execute":"query-block-jobs"}'
  • 预期结果:
  • 删除仍在执行时,block job 存在,连续两次查询的已处理数据量持续增长,且没有存储路径、I/O 或容量错误。
  • 任务已经正常结束时,block job 可以不存在,但管理节点和 Agent 日志应有成功响应,虚拟机磁盘 backing 关系与平台记录一致。
  • 异常处理:
  • virsh blockjob 显示没有任务时,先按时间顺序检查此前是否已经发生 timeout 和 cancel;不要把清理阶段的“没有 active block job”当成首因。
  • block job 存在但连续观察无进度,或日志出现 I/O、iSCSI 路径、VG 容量、快照链错误时,停止重试,保留输出并转 ZStack 技术支持排查底层原因。延长 API timeout 不能修复这些问题。
  • 不要手工执行 blockJobAbort、删除 LV、修改数据库快照状态或重启管理节点来清理现场。

5. 检查快照组的逐成员结果

  • 检查对象:APIDeleteVolumeSnapshotGroupEvent 返回中的 results[],以及每个成员的快照 UUID、卷 UUID、success 和错误信息。
  • 操作位置:在任务详情、API 返回或步骤 2 的管理节点日志中展开完整响应;逐项记录失败的是根硬盘还是数据硬盘。
  • 预期结果:只有 results[] 中所有成员都成功,才能认定快照组删除成功。
  • 异常处理:外层 event 为 success=true、但任意 results[n].success=false 时,仍按删除失败处理。使用失败成员的卷 UUID、快照 UUID 和 Agent taskUuid 回到步骤 4 定位对应 block job。

6. 在受控窗口为正确入口延长超时并重新发起任务

临时方案(Workaround)

  • 适用条件:已经确认真实 API;旧删除任务已结束;当前没有同一虚拟机的快照、备份、合并或迁移任务;虚拟机和磁盘 backing 链状态一致;数据存储/VG 有足够空间;步骤 4 未发现 I/O、路径或链异常;已保存原 GlobalConfig 值,并获得维护窗口和业务批准。
  • 操作位置:在管理节点的 zstack-cli 中,只执行与真实入口匹配的一条更新命令。以下 24 小时值来自已记录案例,是临时观察窗口,不代表所有环境的固定推荐值:
  # 删除一个单盘快照时
  UpdateGlobalConfig category=apiTimeout name=org.zstack.header.storage.snapshot.APIDeleteVolumeSnapshotMsg value=24h

  # 批量删除多个单盘快照时
  UpdateGlobalConfig category=apiTimeout name=org.zstack.header.storage.snapshot.APIBatchDeleteVolumeSnapshotMsg value=24h

  # 删除快照组时
  UpdateGlobalConfig category=apiTimeout name=org.zstack.header.storage.snapshot.group.APIDeleteVolumeSnapshotGroupMsg value=24h
  • 重新发起:修改配置后必须创建一个新的删除请求。旧请求的 deadline 已固定,修改配置不会延长它。新请求开始后立即执行步骤 2,确认 API 请求及 Agent 调用携带 86400000 毫秒和匹配的新 deadline。
  • 观察方法:任务运行期间按固定间隔重复步骤 4 的只读查询,确认 block job 进度持续增长,同时观察数据存储容量、主机 I/O 和业务延迟。快照组还必须检查每个 results[]。
  • 成功判据:新任务在 deadline 内结束;单盘删除返回成功,或快照组的所有成员结果均成功;不再存在对应 block job;虚拟机运行、磁盘 backing 链和平台快照清单一致;没有新增 I/O 或容量告警。
  • 停止条件:block job 长时间无进度、预计无法在维护窗口内完成、出现存储路径/I/O/容量/快照链错误、虚拟机异常,或无法确认快照链一致性时,立即停止继续重试并联系 ZStack 技术支持。不要通过反复加大 timeout 掩盖底层问题。
  • 回退方式:任务成功或失败并确认已完全结束后,将修改过的 GlobalConfig 恢复为步骤 3 记录的原值,再执行 QueryGlobalConfig 确认。恢复原值只影响以后创建的请求,不会取消或缩短已经运行的任务。

补充信息

  • 提交支持信息时,应包含:失败任务截图、API ID、快照/快照组/虚拟机/硬盘 UUID、准确时间窗、三个 API timeout 查询结果、管理节点命中日志、Agent taskUuid 日志、block job 两次以上的进度样本、数据存储容量和异常告警。
  • 已记录案例能证明“快照组入口未调整,3 小时 deadline 到达后取消尚未完成的在线合并”,但不能仅凭该案例把合并慢进一步归因于某块磁盘、iSCSI 路径或 QEMU 缺陷,也不能保证调整为 24 小时后一定完成。
  • 本文中的配置变更属于临时方案。正式长期处置应以底层 block job、存储性能和快照链证据为基础,不应把无限延长超时作为修复。
删除单盘快照或快照组超时,并显示“block job not finished” | 故障排查 · KB | ZStack 资源中心