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

适用版本: 7.1-8.9

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

cannot snapshot shard on a readonly repository 表示 Elasticsearch 已经进入到分片快照写入流程,但发现目标仓库是只读的,因此无法继续把当前分片数据写入仓库。这个错误直接发生在 snapshot shard 的执行路径上,说明问题不在查询、不在分片分配本身,而在仓库写权限和仓库策略。

与“cannot create snapshot in a readonly repository”相比,这个错误更贴近分片级执行阶段,强调的是单个 shard snapshot 无法落盘到仓库。通常意味着快照任务真正开始写数据前,就被仓库只读策略拦住了。

常见现象 #

  • 创建快照任务后,任务可能很快失败,并在 shard 级日志中出现只读仓库报错。
  • 某些场景下快照初始化已开始,但写入分片数据时被拒绝,最终表现为快照失败或部分失败。
  • 仓库本身可能可以查看、校验,但一旦进入写入分片数据的步骤就失败。
  • 业务上常见表现是备份任务失败、SLM 任务报错、部分分片无法完成快照。

典型报错与异常栈 #

这类错误通常会与下面这些关键字一起出现:

  • cannot snapshot shard on a readonly repository
  • repository_exception
  • snapshot_failed_exception
  • partial / failed snapshot state

常见日志形态通常类似下面这样:

RepositoryException: [my_repo] cannot snapshot shard on a readonly repository

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

这个错误的核心原因是:分片快照需要把数据和元数据写入仓库,但当前仓库被显式定义为只读,或者底层权限本身只允许读。Elasticsearch 不会在这种仓库上继续执行 shard snapshot,因为那会破坏只读语义,也可能导致仓库状态不一致。

常见原因通常包括:

  • 仓库 settings 中配置了 readonly: true
  • 底层对象存储/共享目录权限仅允许读访问。
  • SLM 或人工快照任务错误地指向了一个恢复仓库或只读副本仓库。
  • 仓库原本应当可写,但环境迁移后权限或配置被改成了只读。

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

建议按“先确认仓库是不是只读,再确认快照任务是不是指向了正确仓库”的顺序处理:

  1. 查看仓库配置,确认 readonly 设置和仓库用途。
  2. 查看快照任务状态,确认是所有 shard 都失败,还是部分 shard 在写入阶段失败。
  3. 核对 SLM 策略或人工快照接口是否把目标仓库设错了。
  4. 如果仓库本应可写,继续检查底层存储权限是否真正允许写入。

相关 Elasticsearch API 及调用说明 #

1. 查看仓库配置 #

curl -X GET "http://localhost:9200/_snapshot/my_repo?pretty"

确认 settings.readonly 和仓库类型。

2. 创建快照 #

curl -X PUT "http://localhost:9200/_snapshot/my_repo/snapshot_2026_03_31?wait_for_completion=true&pretty"

如果仓库只读,这个调用可能会在执行过程中失败,或者很快返回只读相关异常。

3. 查看快照状态 #

curl -X GET "http://localhost:9200/_snapshot/my_repo/snapshot_2026_03_31/_status?pretty"

适合确认是哪个 shard 失败,以及失败阶段是否与仓库写入有关。

4. 查看集群中的快照任务 #

curl -X GET "http://localhost:9200/_tasks?pretty&actions=*snapshot*"

用于确认当前快照任务是否仍在进行,还是已经被只读异常终止。

排查时需要注意的问题 #

  • 这类错误首先看仓库权限,不要先把问题归因到某个 shard 损坏。
  • 如果是 SLM 周期任务失败,优先核查策略绑定的仓库名称是不是被错误替换了。
  • 把仓库改成可写之前,先确认底层权限和运维策略也一致,否则逻辑配置和实际权限会继续冲突。

4. 如何解决这个错误 #

常用修复思路 #

  • 如果任务指向错误仓库,改用正确的可写快照仓库重新执行。
  • 如果仓库本应允许快照写入,修正 readonly 配置并同步修复底层权限。
  • 对失败的快照任务重新发起,不要在同一个只读仓库上反复重试。

后续注意事项与推荐建议 #

  • 为快照仓库建立清晰的“写仓库/恢复仓库”分层,避免只读仓库被误用于备份。
  • 对 SLM 和手工快照入口增加仓库可写性校验。
  • 为 snapshot failed、partial 状态建立专门告警,尽早发现仓库策略错误。

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

  • INFINI Console 适合观察快照任务失败趋势、仓库状态和节点事件,帮助快速确认是不是仓库只读导致分片快照失败。
  • INFINI Gateway 适合保留快照接口调用审计,便于排查是谁把任务发到了只读仓库。

5. 小结 #

cannot snapshot shard on a readonly repository 的核心是仓库不可写,而不是 shard 本身不可读。只要目标仓库仍是只读,分片快照写入就不会成功。

最有效的处理方式,是先把仓库职责和权限理顺,再重新发起快照。对备份链路来说,提前识别只读仓库误用要比事后追查快照失败更高效。

附:日志上下文 #

下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:

shardSnapshotTaskRunner.enqueueShardSnapshot(context);
 }  private void doSnapshotShard(SnapshotShardContext context) {
 if (isReadOnly()) {
 context.onFailure(new RepositoryException(metadata.name(); "cannot snapshot shard on a readonly repository"));
 return;
 }
 final Store store = context.store();
 final ShardId shardId = store.shardId();
 final SnapshotId snapshotId = context.snapshotId();