为什么这个错误发生 #
index_shard_recovering_exception 表示尝试对正在进行恢复(recovering)的分片执行不允许的操作。当分片处于恢复状态时,某些操作(如再次启动恢复)会被拒绝。
这个错误可能由以下原因引起:
- 分片正在恢复:分片当前正在执行恢复操作
- 并发恢复请求:同时发起了多个恢复请求
- 分片处于恢复后状态:分片处于 POST_RECOVERY 状态
- 节点重启后:节点重启后分片正在进行恢复
- 副本恢复:副本分片正在从主分片恢复数据
- 快照恢复:从快照恢复分片时发生
- ** relocation 过程**:分片正在迁移到另一个节点
- 恢复未完成:之前的恢复操作尚未完成
如何修复这个错误 #
1. 检查分片状态 #
# 查看分片当前状态
GET /_cat/shards?v&h=index,shard,prirep,state,node
# 查看特定索引的分片状态
GET /<index>/_shard_stores?status=recovering
# 查看分片恢复状态
GET /<index>/_recovery?active_only=true
2. 等待恢复完成 #
# 等待当前恢复操作完成
GET /_cat/recovery?v
# 查看恢复进度
GET /_cat/recovery?v&h=index,shard,bytes,bytes_pct,stage
# 等待集群状态变为绿色
GET /_cluster/health?wait_for_status=green&timeout=300s
3. 取消恢复(如果卡住) #
# 如果恢复卡住,可以尝试取消并重新分配
POST /_cluster/reroute
{
"commands": [
{
"cancel": {
"index": "<index>",
"shard": 0,
"node": "<node_name>"
}
}
]
}
# 然后重新分配
POST /_cluster/reroute
{
"commands": [
{
"allocate_replica": {
"index": "<index>",
"shard": 0,
"node": "<node_name>"
}
}
]
}
4. 强制分配分片 #
# 如果恢复失败,可以尝试强制分配
POST /_cluster/reroute
{
"commands": [
{
"allocate_stale_primary": {
"index": "<index>",
"shard": 0,
"node": "<node_name>",
"accept_data_loss": true
}
}
]
}
5. 从快照恢复 #
# 如果恢复失败,可以从快照重新恢复
POST /_snapshot/<repository>/<snapshot_name>/_restore
{
"indices": "<index>",
"include_global_state": false
}
# 查看可用的快照
GET /_snapshot/<repository>/_all
6. 重启节点 #
# 在承载问题分片的节点上重启服务
sudo systemctl restart easysearch
# 等待节点加入集群
GET /_cat/nodes?v
7. 删除并重建索引 #
# 如果没有重要数据,可以删除并重建索引
DELETE /<index>
# 重新创建索引
PUT /<index>
# 从数据源重新导入数据
8. 检查恢复配置 #
# 在 easysearch.yml 中调整恢复配置
cluster.routing.allocation.node_initial_primaries_recoveries: 4
cluster.routing.allocation.node_concurrent_recoveries: 2
indices.recovery.max_bytes_per_sec: 50mb
9. 查看恢复详情 #
# 查看详细的恢复信息
GET /<index>/_recovery?active_only=true&detailed=true
# 查看所有分片的恢复状态
GET /_recovery?human&detailed=true
10. 检查磁盘空间 #
# 确保有足够的磁盘空间进行恢复
GET /_cat/allocation?v
# 查看磁盘使用
df -h /path/to/easysearch/data
11. 增加恢复并发数 #
# 如果有很多分片需要恢复,可以增加并发数
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.node_concurrent_recoveries": 6,
"cluster.routing.allocation.node_initial_primaries_recoveries": 8
}
}
12. 限制恢复带宽 #
# 避免恢复占用过多带宽
PUT /<index>/_settings
{
"index": {
"recovery": {
"max_bytes_per_sec": "20mb"
}
}
}
13. 检查节点日志 #
# 查看恢复相关错误日志
grep -i "recover\|restore" /path/to/easysearch/logs/easysearch.log | tail -100
# 查看分片相关日志
grep -i "shard.*error" /path/to/easysearch/logs/easysearch.log | tail -50
14. 重置分片分配 #
# 重新启用分片分配
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.enable": "all"
}
}
# 触发重新分配
POST /_cluster/reroute?retry_failed=true
预防措施 #
- 优雅关闭节点(避免强制终止)
- 保持足够的磁盘空间
- 配置合理的恢复速度限制
- 监控恢复进度
- 使用快照备份重要数据
- 避免频繁的分片迁移
- 配置足够的副本数
- 监控集群健康状态
- 在低峰期执行节点维护
- 使用滚动重启而非同时重启多个节点





