📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 7.1-8.9

1. 错误异常的基本描述 #

snapshot with the same name is already in-progress 表示你试图创建的快照名称,已经被同一仓库中一个活跃的快照任务占用。根据源码,Elasticsearch 会先遍历 runningSnapshots.forRepo(repositoryName),只要发现有正在执行的快照名称与本次请求相同,就直接抛出 SnapshotNameAlreadyInUseException

它比 a snapshot is already running 更具体:不是仓库上任意快照在运行,而是“这个名字本身已经在运行中”。

常见现象 #

  • 自动化任务因重试过快,同一个快照名被重复提交。
  • 一次快照尚未结束,运维又用同名手工触发第二次。
  • 客户端看到同一个仓库、同一个快照名持续返回并发占用异常。
  • 失败后立刻重试但仍沿用旧名字,会稳定复现。

典型报错与异常栈 #

SnapshotNameAlreadyInUseException: [repo:snap-20260331] snapshot with the same name is already in-progress

2. 为什么会发生这个错误 #

快照创建前,Elasticsearch 不仅检查仓库里是否已有历史同名快照,也会检查运行中的快照集合。只要运行态里已有相同名称,就不能再提交第二个同名任务。

常见原因通常包括:

  • 自动化重试逻辑固定使用一个快照名。
  • SLM 或外部调度在网络抖动后重复提交同一任务。
  • 前一个同名快照运行时间很长,而后续请求没有感知到它仍在运行。
  • 人工排障时误把“同名已在执行中”当成“上一次已经失败结束”。

3. 如何排查和解决这个异常和解决这个异常 #

建议按“先确认旧任务是否还活着,再决定等待还是换名重提”的顺序处理:

  1. 查看当前仓库的运行中快照,确认该名称是否真的还在执行。
  2. 查看提交来源,判断是人工重复、SLM 重试还是外部脚本重复触发。
  3. 如果旧任务仍正常运行,等待结束后再提交。
  4. 如果确实要重新创建,使用新的快照名,并先确认旧任务最终状态。

相关 Elasticsearch API #

  • GET /_snapshot/{repository}/_current:查看是否存在同名活跃快照。
  • GET /_snapshot/{repository}/{snapshot}:确认该名称是否已作为历史快照存在。
  • PUT /_snapshot/{repository}/{snapshot}:在更换名称或等待旧任务结束后重新创建。

排查时需要注意的问题 #

  • 这和 snapshot with the same name already exists 不同,后者指历史记录已存在,前者指运行中记录仍存在。
  • 不要在未确认旧任务最终状态前立即更换名称继续提交,否则容易制造多份重复备份。
  • 如果使用时间戳命名,重点检查时间戳精度是否足够避免秒级碰撞。

4. 如何解决这个错误 #

常用修复思路 #

  • 等当前同名快照结束后再重试。
  • 使用唯一快照名,例如带更高精度时间戳或任务 ID。
  • 给自动化任务增加幂等检查,先查 _current 再决定是否发起创建。
  • 修复重复触发源,避免网络抖动时无限重发同一个名字。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 可查看同仓库下快照运行状态与历史提交记录。
  • INFINI Gateway 可审计重复快照请求是否来自同一调用源。

5. 小结 #

snapshot with the same name is already in-progress 的重点是名称冲突发生在运行态,而不是历史态。正确处理方式是先确认旧任务状态,再决定等待它完成还是改名重新提交。

相关错误 #

附:日志上下文 #

private static void ensureSnapshotNameNotRunning(SnapshotsInProgress runningSnapshots, String repositoryName, String snapshotName) {
	if (runningSnapshots.forRepo(repositoryName).stream()
		.anyMatch(s -> s.snapshot().getSnapshotId().getName().equals(snapshotName))) {
		throw new SnapshotNameAlreadyInUseException(repositoryName, snapshotName, "snapshot with the same name is already in-progress");
	}
}