--- title: "分片不处于主模式异常 (shard_not_in_primary_mode_exception) 错误排查与解决" date: 2026-02-16 lastmod: 2026-02-16 description: "shard_not_in_primary_mode_exception 表示分片当前不处于主模式,但操作要求分片必须是主分片。通常发生在对副本分片执行只有主分片才能执行的操作时。" tags: ["分片", "主分片", "集群管理"] summary: "为什么这个错误发生 # shard_not_in_primary_mode_exception 表示分片当前不处于主模式(primary mode),但操作要求分片必须是主分片。这通常发生在尝试对副本分片执行只有主分片才能执行的操作时。 这个错误可能由以下原因引起: 分片是副本:操作针对的是副本分片而非主分片 主分片迁移中:主分片正在迁移到其他节点 分片恢复中:分片正在恢复过程中 分片状态转换:分片正在进行状态转换 主分片故障:主分片故障,副本尚未提升 并发操作冲突:并发操作导致分片状态混乱 节点角色变化:节点角色从主节点变为副本节点 如何修复这个错误 # 1. 检查分片状态 # # 查看分片状态和类型 GET /_cat/shards?v&h=index,shard,prirep,state,node # 查看特定索引的分片 GET /_cat/shards/<index>?v 2. 定位主分片 # # 找到主分片所在节点 GET /_cat/shards?v&h=index,shard,prirep,state,node | grep "<index>" | grep "p" # 或使用 GET /_cluster/state?filter_path=**.routing_table 3. 对主分片执行操作 # # 确保操作针对主分片而非副本 # 在 API 请求中指定偏好 GET /<index>/_search?preference=_primary 4. 等待主分片恢复 # # 如果主分片故障,等待其恢复或副本提升 GET /_cat/shards?v&h=index,shard,prirep,state # 等待集群恢复 GET /_cluster/health?" --- ## 为什么这个错误发生 `shard_not_in_primary_mode_exception` 表示分片当前不处于主模式(primary mode),但操作要求分片必须是主分片。这通常发生在尝试对副本分片执行只有主分片才能执行的操作时。 这个错误可能由以下原因引起: 1. **分片是副本**:操作针对的是副本分片而非主分片 2. **主分片迁移中**:主分片正在迁移到其他节点 3. **分片恢复中**:分片正在恢复过程中 4. **分片状态转换**:分片正在进行状态转换 5. **主分片故障**:主分片故障,副本尚未提升 6. **并发操作冲突**:并发操作导致分片状态混乱 7. **节点角色变化**:节点角色从主节点变为副本节点 ## 如何修复这个错误 ### 1. 检查分片状态 ```bash # 查看分片状态和类型 GET /_cat/shards?v&h=index,shard,prirep,state,node # 查看特定索引的分片 GET /_cat/shards/?v ``` ### 2. 定位主分片 ```bash # 找到主分片所在节点 GET /_cat/shards?v&h=index,shard,prirep,state,node | grep "" | grep "p" # 或使用 GET /_cluster/state?filter_path=**.routing_table ``` ### 3. 对主分片执行操作 ```bash # 确保操作针对主分片而非副本 # 在 API 请求中指定偏好 GET //_search?preference=_primary ``` ### 4. 等待主分片恢复 ```bash # 如果主分片故障,等待其恢复或副本提升 GET /_cat/shards?v&h=index,shard,prirep,state # 等待集群恢复 GET /_cluster/health?wait_for_status=green&timeout=50s ``` ### 5. 手动提升副本为主分片 ```bash # 如果主分片永久丢失,可以强制提升副本 POST /_cluster/reroute { "commands": [ { "allocate_stale_primary": { "index": "", "shard": 0, "node": "", "accept_data_loss": true } } ] } ``` ### 6. 等待分片迁移完成 ```bash # 如果主分片正在迁移,等待迁移完成 GET /_cat/recovery?v&active_only=true # 查看迁移进度 GET /_cluster/allocation/explain?pretty ``` ### 7. 检查节点状态 ```bash # 确保承载主分片的节点在线 GET /_cat/nodes?v&h=name,status # 查看节点详细信息 GET /_nodes ``` ### 8. 重启节点 ```bash # 如果节点状态异常,重启该节点 sudo systemctl restart easysearch # 等待节点重新加入集群 GET /_cat/nodes?v ``` ### 9. 重新分配分片 ```bash # 触发分片重新分配 POST /_cluster/reroute?retry_failed=true # 手动分配 POST /_cluster/reroute { "commands": [ { "allocate_replica": { "index": "", "shard": 0, "node": "" } } ] } ``` ### 10. 查看错误日志 ```bash # 查看分片状态相关错误日志 grep -i "shard.*mode\|primary.*mode" /path/to/easysearch/logs/easysearch.log | tail -100 # 查看分片相关错误 grep -i "shard.*error\|primary.*fail" /path/to/easysearch/logs/easysearch.log | tail -50 ``` ### 11. 检查集群状态 ```bash # 确保集群状态正常 GET /_cluster/health?v # 查看集群状态详情 GET /_cluster/state?filter_path=**.routing_table ``` ### 12. 验证索引配置 ```bash # 检查索引的副本配置 GET //_settings?filter_path=**.number_of_replicas # 确保有足够的副本 ``` ### 13. 处理并发操作 ```bash # 如果是并发操作导致的问题,减少并发 # 或实现操作队列 ``` ### 14. 从快照恢复 ```bash # 如果无法恢复主分片,从快照恢复 POST /_snapshot///_restore { "indices": "", "include_global_state": false } ``` ### 15. 等待分片初始化 ```bash # 如果分片正在初始化,等待初始化完成 GET /_cat/shards?v&h=index,shard,prirep,state,init_phase # 等待所有分片初始化完成 GET /_cluster/health?wait_for_no_initializing_shards=true&timeout=50s ``` ### 预防措施 - 配置足够的副本数 - 监控主分片健康状态 - 实现故障自动转移 - 优雅关闭节点 - 使用滚动重启 - 监控集群健康状态 - 实现客户端重试 - 处理分片状态转换 - 监控分片分配 - 使用快照备份