适用版本: 6.8-8.9
1. 错误异常的基本描述 #
failed to load started shards 出现在节点 gateway 读取本地分片状态的流程里。源码在返回 NodeGatewayStartedShards 前捕获通用异常并抛出当前错误,因此问题通常与节点本地 shard state 文件、分片目录或恢复状态有关,而不是普通网络请求失败。
这不是"分片还没启动",而是"本地已启动分片状态读不出来"。
常见现象 #
- 节点启动后,分片分配或主副本恢复异常,分片可能长时间处于
INITIALIZING或UNASSIGNED状态。 - 集群请求节点上报 started shards 信息时失败,导致恢复判断不完整。
- 某个节点反复报错,而同一索引在其他节点可能正常。
- 在 Kibana 的集群健康界面中,可能看到分片分配失败或恢复停滞。
- Elasticsearch 日志中可以看到
failed to load started shards关键字,伴随IOException或状态解析异常。
典型报错与异常栈 #
常见日志形态通常类似下面这样:
ElasticsearchException: failed to load started shards
Caused by: java.io.FileNotFoundException: /path/to/elasticsearch/data/nodes/0/indices/{index_uuid}/{shard_id}/state
at java.io.FileInputStream.open0(Native Method)
或者状态文件损坏:
ElasticsearchException: failed to load started shards
Caused by: java.io.IOException: Unexpected end of file
at org.elasticsearch.common.xcontent.XContentHelper...
或者磁盘 I/O 错误:
ElasticsearchException: failed to load started shards
Caused by: java.io.IOException: Input/output error
at java.io.FileInputStream.readBytes(Native Method)
2. 为什么会发生这个错误 #
failed to load started shards 的根因是"本地已启动分片状态不可读"。Elasticsearch 在节点启动时需要从本地磁盘读取分片状态信息(shard_state 文件),以确定哪些分片已经启动;如果状态文件有问题,就会导致此异常。
常见原因通常包括:
- 本地分片 state 文件问题:本地分片 state 文件缺失、损坏或格式异常(如
state-*.st文件)。 - 磁盘或文件系统问题:节点磁盘、挂载目录或文件系统出现问题,导致读取中断。
- 残留不完整数据:节点上残留不完整的 shard 数据目录,例如异常重启或手工清理后留下半成品。
- 升级或迁移遗留问题:升级、迁移或恢复过程中,本地 shard metadata 与集群视图不一致。
- 异常重启或强制终止:Elasticsearch 进程被强制 kill(
kill -9),导致状态文件写入不完整。 - 手工目录操作:手工修改分片目录(如直接删除文件),导致状态信息不一致。
- 磁盘空间不足:磁盘空间不足导致状态文件无法正确写入或读取。
- 文件权限问题:Elasticsearch 用户没有读取分片状态文件的权限。
3. 如何排查和解决这个异常和解决这个异常 #
建议按"先检查节点本地目录、再检查磁盘健康、后修复分片状态"的顺序处理:
检查报错节点的本地分片目录:在报错节点上检查对应索引和分片目录是否完整,确认 state 文件存在。
# 查看节点本地分片目录 ls -la /path/to/elasticsearch/data/nodes/0/indices/ # 查看特定索引的分片目录 ls -la /path/to/elasticsearch/data/nodes/0/indices/{index_uuid}/ # 检查 state 文件是否存在 find /path/to/elasticsearch/data/nodes/0/indices/ -name "state*"查看节点日志和系统日志:查看节点日志与系统日志,检查磁盘 I/O、文件系统和挂载异常。
# 查看 Elasticsearch 日志 grep -r "failed to load started shards" /var/log/elasticsearch/ grep -r "IOException\|state" /var/log/elasticsearch/ | tail -50 # 查看系统日志中的磁盘错误 dmesg | grep -i "error\|io\|ext4\|xfs" # 检查磁盘空间 df -h对比主副本节点:对比主副本节点的本地目录,判断是否只有单节点数据损坏。
# 查看分片分配 curl -X GET "localhost:9200/_cat/shards/my_index?v" # 查看分片分配解释 curl -X GET "localhost:9200/_cluster/allocation/explain?pretty"检查分片历史操作:检查该分片最近是否经历了异常重启、迁移中断或手工目录操作。
# 查看 Elasticsearch 日志中的分片相关记录 grep -r "shard.*my_index\|recovery.*my_index" /var/log/elasticsearch/ | tail -100检查健康副本:如有健康副本,优先考虑从副本恢复,而不是在损坏目录上反复重试。
# 查看索引的健康副本 curl -X GET "localhost:9200/_cat/shards/my_index?v&h=index,shard,prirep,state,node"
排查时需要注意的问题 #
- 这个错误是本地分片状态问题,不是集群状态或分片分配策略问题,需要重点关注节点本地存储,而不是集群层面的设置。
- 如果问题只在某些节点上出现,很可能是节点本地状态文件的问题,需要检查节点间的状态一致性。
- 手工修改分片目录(如在数据目录下直接删除文件)是高风险操作,容易导致状态不一致。
4. 如何解决这个错误 #
常用修复思路 #
修复节点磁盘或挂载问题:修复节点磁盘或挂载问题,确保本地 shard state 可以稳定读取。
# 检查并修复文件系统(需要停机操作) fsck /dev/sdX # 检查文件句柄使用 lsof -p $(pgrep -f elasticsearch) | wc -l清理并恢复损坏的分片目录:对损坏的本地分片目录执行安全清理,再由集群从健康副本重新分配。
# 停止 Elasticsearch 节点 systemctl stop elasticsearch # 备份并清理损坏的分片目录(谨慎操作) mv /path/to/elasticsearch/data/nodes/0/indices/{index_uuid}/{shard_id} /tmp/shard_backup # 重启节点,让集群从副本恢复 systemctl start elasticsearch从健康副本恢复:恢复或重建异常分片,避免继续依赖不完整的本地状态。
# 尝试分配副本分片 curl -X POST "localhost:9200/_cluster/reroute" -H 'Content-Type: application/json' -d' { "commands": [ { "allocate_replica": { "index": "my_index", "shard": 0, "node": "target_node_name" } } ] } '重建索引:如果多个分片都有问题,考虑重建整个索引。
# 重建索引 curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d' { "source": { "index": "old_index" }, "dest": { "index": "new_index" } } '加强节点运维规范:避免手工修改分片目录或在恢复期间强制中断。
# 正确停止 Elasticsearch 节点(不要使用 kill -9) systemctl stop elasticsearch # 或者使用 API curl -X POST "localhost:9200/_cluster/nodes/{node_id}/_shutdown"
后续注意事项与推荐建议 #
- 建立节点本地状态的监控,定期检查分片目录的完整性和健康度。
- 避免手工修改数据目录,所有分片操作都应通过 Elasticsearch API 完成。
- 在升级 Elasticsearch 版本前,仔细阅读升级说明,必要时先备份数据。
- 为节点磁盘空间、I/O 等待和文件系统错误配置监控和告警,在问题影响分片状态前及时通知。
- 对于重要索引,配置至少 1 个副本分片,确保在主分片本地状态损坏时可以快速恢复。
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合查看集群的分片状态、节点存储、恢复进度和错误趋势,帮助快速定位
failed to load started shards是本地状态问题、磁盘问题还是恢复不一致问题,并提供可视化的分片管理和修复操作。 - INFINI Gateway 可以记录所有恢复相关的请求日志,帮助定位分片恢复失败的具体环节,同时提供请求审计功能。
- 建议将分片状态、恢复成功率、磁盘健康度和节点错误统一接入监控面板,结合 INFINI Console 的告警功能,在分片状态加载失败时及时通知管理员。
5. 小结 #
failed to load started shards 的关键是"本地已启动分片状态不可读"。排查重点应放在节点本地磁盘、分片目录和 shard state 文件健康度,而不是只看分配结果表面现象。大多数情况下,这个问题可以通过修复磁盘问题、清理损坏目录和从健康副本恢复来解决。
只要把节点本地状态监控、磁盘健康管理和恢复策略固定下来,大多数分片状态加载类异常都可以被有效预防,也更容易通过 INFINI Console 和 INFINI Gateway 实现持续防护。
相关错误 #
- all-shards-failed-how-to-solve-this-elasticsearch-exception
- failed-to-list-store-metadata-for-shard-request-shardid-how-to-solve-this-elasticsearch-exception
- unable-to-find-the-latest-snapshot-for-shard-shardid-how-to-solve-this-elasticsearch-exception
- corrupt-index-how-to-solve-this-elasticsearch-exception
- gateway-timeout-how-to-solve-this-elasticsearch-exception
参考文档 #
- Elasticsearch Gateway 官方文档
- Elasticsearch 分片恢复官方文档
- Elasticsearch 节点启动官方文档
- INFINI Console 文档
- INFINI Gateway 文档
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
return new NodeGatewayStartedShards(clusterService.localNode(), allocationId, shardStateMetadata.primary);
}
logger.trace("{} no local shard info found", shardId);
return new NodeGatewayStartedShards(clusterService.localNode(), null, false);
} catch (Exception e) {
throw new ElasticsearchException("failed to load started shards", e);
}





