适用版本: 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 repositoryrepository_exceptionsnapshot_failed_exceptionpartial/failedsnapshot state
常见日志形态通常类似下面这样:
RepositoryException: [my_repo] cannot snapshot shard on a readonly repository
2. 为什么会发生这个错误 #
这个错误的核心原因是:分片快照需要把数据和元数据写入仓库,但当前仓库被显式定义为只读,或者底层权限本身只允许读。Elasticsearch 不会在这种仓库上继续执行 shard snapshot,因为那会破坏只读语义,也可能导致仓库状态不一致。
常见原因通常包括:
- 仓库 settings 中配置了
readonly: true。 - 底层对象存储/共享目录权限仅允许读访问。
- SLM 或人工快照任务错误地指向了一个恢复仓库或只读副本仓库。
- 仓库原本应当可写,但环境迁移后权限或配置被改成了只读。
3. 如何排查和解决这个异常和解决这个异常 #
建议按“先确认仓库是不是只读,再确认快照任务是不是指向了正确仓库”的顺序处理:
- 查看仓库配置,确认
readonly设置和仓库用途。 - 查看快照任务状态,确认是所有 shard 都失败,还是部分 shard 在写入阶段失败。
- 核对 SLM 策略或人工快照接口是否把目标仓库设错了。
- 如果仓库本应可写,继续检查底层存储权限是否真正允许写入。
相关 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();





