为什么这个错误发生 #
index_shard_not_recovering_exception 表示尝试对分片执行恢复相关操作,但分片当前不在恢复状态。分片恢复是指将数据从副本或快照恢复到分片的过程。
这个错误可能由以下原因引起:
- 分片已启动:分片已经完成恢复并启动,不再处于恢复状态
- 分片未开始恢复:分片尚未开始恢复过程
- 恢复已完成:恢复操作已经完成
- 恢复失败:恢复操作失败,分片状态已变更
- 分片被关闭:分片被关闭,无法执行恢复
- 状态转换:分片状态在操作过程中发生变化
- 并发操作冲突:其他操作导致分片状态改变
- 手动取消:恢复操作被手动取消或中断
如何修复这个错误 #
1. 检查分片状态 #
# 查看分片详细状态
GET /_cat/shards?v&h=index,shard,prirep,state,unassigned.reason,init
# 查看特定分片
GET /_cluster/allocation/explain
{
"index": "<index>",
"shard": 0
}
2. 查看恢复状态 #
# 查看正在恢复的分片
GET /_cat/recovery?v&active_only=true
# 查看恢复详细进度
GET /<index>/_recovery?active_only=true
3. 等待恢复完成或开始 #
# 如果分片正在恢复,等待完成
GET /_cluster/health?wait_for_no_initializing_shards=true&timeout=50s
# 如果需要触发恢复
POST /_cluster/reroute?retry_failed=true
4. 检查分片是否已可用 #
# 如果分片已启动(正常状态),无需恢复
# 可以直接执行操作
GET /<index>/_search
{
"query": {
"match_all": {}
}
}
5. 触发分片恢复 #
# 从快照恢复分片
POST /_snapshot/<repository>/<snapshot>/_restore
{
"indices": "<index>"
}
# 或重新分配分片
POST /_cluster/reroute
{
"commands": [{
"allocate_stale_primary": {
"index": "<index>",
"shard": 0,
"node": "<node_name>",
"accept_data_loss": false
}
}]
}
6. 从副本恢复 #
# 如果有健康的副本,可以从副本恢复主分片
POST /_cluster/reroute
{
"commands": [{
"allocate_stale_primary": {
"index": "<index>",
"shard": 0,
"node": "<node_with_replica>",
"accept_data_loss": false
}
}]
}
7. 检查节点日志 #
# 查看恢复相关日志
grep -i "recover.*shard\|shard.*recover" /path/to/easysearch/logs/easysearch.log | tail -100
# 查找错误信息
grep -i "failed.*recover" /path/to/easysearch/logs/easysearch.log | tail -50
8. 重置分片状态(谨慎使用) #
# 如果分片状态异常,可能需要重置
# 首先尝试重新分配
POST /_cluster/reroute?retry_failed=true
# 如果无效,可能需要删除并重建分片
# 这会导致数据丢失,请谨慎操作
9. 检查恢复配置 #
# 查看恢复相关设置
GET /_cluster/settings?filter_path=**.indices.recovery
# 调整恢复设置
PUT /_cluster/settings
{
"transient": {
"indices.recovery.max_bytes_per_sec": "50mb",
"indices.recovery.concurrent_streams": 4
}
}
10. 使用副本读取数据 #
# 如果主分片正在恢复,可以使用副本读取
GET /<index>/_search?preference=_replica
预防措施 #
- 确保分片正常启动和运行
- 监控恢复操作状态
- 避免在恢复时执行其他操作
- 配置足够的副本提高可用性
- 使用快照保护重要数据
- 监控分片健康状态
- 在分片稳定后执行操作





