📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 7.17-8.9

1. 错误异常的基本描述 #

not all primary shards of [databases] index are active 通常出现在 GeoIP downloader 或相关内部流程检查 .geoip_databases 写索引状态时。它的含义很具体: 该内部索引的所有主分片还没有全部进入 active 状态,所以后续写入或更新流程被阻止。

常见现象 #

  • GeoIP 数据库更新失败或延迟。
  • 节点日志里出现与 GeoIpDownloader.DATABASES_INDEX 相关的异常。
  • 集群总体可能不是完全 red,但 .geoip_databases 写索引的主分片尚未准备好。

典型报错与异常栈 #

ElasticsearchException: not all primary shards of [.geoip_databases] index are active

2. 为什么会发生这个错误 #

从源码看,在写入 GeoIP databases 索引前,Elasticsearch 会先检查该写索引的 routing table,只要 allPrimaryShardsActive()false,就直接抛出这个异常。常见原因包括:

  • .geoip_databases 索引的主分片仍在初始化、恢复或重新分配。
  • 承载该内部索引主分片的节点刚重启、离线或资源异常。
  • 磁盘水位、分片分配过滤或集群块导致主分片迟迟不能 active。
  • 集群刚启动完成不久,GeoIP 更新线程比主分片就绪更早触发。

3. 如何排查和解决这个异常和解决这个异常 #

重点排查 .geoip_databases 这个内部索引的主分片为什么没起来。

  1. 查看该索引的分片状态:
GET /_cat/shards/.geoip_databases?v
GET /_cluster/health/.geoip_databases?level=shards
  1. 如果存在未分配或初始化中的主分片,使用分配解释接口查看原因。
  2. 检查节点是否刚重启、磁盘是否超水位、是否存在索引写入 block。
  3. 查看主节点日志,确认是否还伴随 cluster block、恢复失败或内部索引创建异常。
  4. 如果只是集群刚启动阶段的短暂现象,待主分片 active 后通常会自动恢复。

排查时需要注意的问题 #

  • 这是内部系统索引就绪问题,不是普通业务索引写入逻辑错误。
  • 即使业务索引基本正常,.geoip_databases 自己的主分片不 active 也会阻塞 GeoIP 数据库更新。
  • 不要忽略 cluster block 检查,源码里在主分片检查后还会继续检查写入 block。

4. 如何解决这个错误 #

常用修复思路 #

  • 如果主分片只是在恢复中,等待恢复完成或修复恢复卡顿原因。
  • 如果分片因节点或磁盘问题无法 active,优先恢复节点可用性或释放磁盘压力。
  • 如果内部索引被 block,解除相关 block 后重试写入流程。
  • 如果该错误反复出现,检查 GeoIP downloader 运行时机和集群启动顺序,避免内部任务早于索引就绪。

相关 Elasticsearch API #

  • GET /_cat/shards/.geoip_databases?v:查看内部索引分片状态。
  • GET /_cluster/health/.geoip_databases?level=shards:查看主分片是否 active。
  • GET /_cluster/allocation/explain:分析主分片不可分配原因。

借助 INFINI 产品提升排障效率 #

  • INFINI Console 可帮助把内部索引状态、节点资源和错误日志放在同一视图里,便于判断是启动时序问题还是分片故障。
  • INFINI Gateway 对内部系统索引帮助有限,但可以辅助排除外部写入流量干扰。

5. 小结 #

not all primary shards of [databases] index are active 的核心是 .geoip_databases 写索引尚未就绪。排查时要聚焦内部索引的主分片状态、节点可用性和 cluster block,而不是泛泛地从普通搜索或网络故障入手。

相关错误 #

附:日志上下文 #

var geoipIndex = clusterState.getMetadata().getIndicesLookup().get(GeoIpDownloader.DATABASES_INDEX);
if (geoipIndex != null) {
	if (clusterState.getRoutingTable().index(geoipIndex.getWriteIndex()).allPrimaryShardsActive() == false) {
		throw new ElasticsearchException("not all primary shards of [" + DATABASES_INDEX + "] index are active");
	}
}