14
14
import org .elasticsearch .cluster .ClusterState ;
15
15
import org .elasticsearch .cluster .RestoreInProgress ;
16
16
import org .elasticsearch .cluster .health .ClusterHealthStatus ;
17
- import org .elasticsearch .cluster .health .ClusterStateHealth ;
18
17
import org .elasticsearch .cluster .metadata .AutoExpandReplicas ;
19
18
import org .elasticsearch .cluster .metadata .IndexMetadata ;
20
19
import org .elasticsearch .cluster .metadata .Metadata ;
21
20
import org .elasticsearch .cluster .metadata .SingleNodeShutdownMetadata ;
22
21
import org .elasticsearch .cluster .metadata .SingleNodeShutdownMetadata .Type ;
23
22
import org .elasticsearch .cluster .node .DiscoveryNode ;
23
+ import org .elasticsearch .cluster .routing .IndexRoutingTable ;
24
+ import org .elasticsearch .cluster .routing .IndexShardRoutingTable ;
24
25
import org .elasticsearch .cluster .routing .RerouteService ;
25
26
import org .elasticsearch .cluster .routing .RoutingNode ;
26
27
import org .elasticsearch .cluster .routing .RoutingNodes ;
39
40
import org .elasticsearch .common .util .set .Sets ;
40
41
import org .elasticsearch .gateway .GatewayAllocator ;
41
42
import org .elasticsearch .gateway .PriorityComparator ;
43
+ import org .elasticsearch .rest .RestStatus ;
42
44
import org .elasticsearch .snapshots .SnapshotsInfoService ;
43
45
44
46
import java .util .ArrayList ;
55
57
56
58
import static java .util .Collections .emptyList ;
57
59
import static java .util .Collections .singletonList ;
60
+ import static org .elasticsearch .cluster .health .ClusterShardHealth .getInactivePrimaryHealth ;
58
61
import static org .elasticsearch .cluster .routing .UnassignedInfo .INDEX_DELAYED_NODE_LEFT_TIMEOUT_SETTING ;
59
62
60
63
/**
@@ -168,7 +171,7 @@ private static ClusterState buildResultAndLogHealthChange(ClusterState oldState,
168
171
}
169
172
final ClusterState newState = newStateBuilder .build ();
170
173
171
- logClusterHealthStateChange (new ClusterStateHealth ( oldState ), new ClusterStateHealth ( newState ) , reason );
174
+ logClusterHealthStateChange (oldState , newState , reason );
172
175
173
176
return newState ;
174
177
}
@@ -495,13 +498,10 @@ public ClusterState reroute(ClusterState clusterState, String reason) {
495
498
return buildResultAndLogHealthChange (clusterState , allocation , reason );
496
499
}
497
500
498
- private static void logClusterHealthStateChange (
499
- ClusterStateHealth previousStateHealth ,
500
- ClusterStateHealth newStateHealth ,
501
- String reason
502
- ) {
503
- ClusterHealthStatus previousHealth = previousStateHealth .getStatus ();
504
- ClusterHealthStatus currentHealth = newStateHealth .getStatus ();
501
+ private static void logClusterHealthStateChange (final ClusterState previousState , final ClusterState newState , String reason ) {
502
+ ClusterHealthStatus previousHealth = getHealthStatus (previousState );
503
+ ClusterHealthStatus currentHealth = getHealthStatus (newState );
504
+
505
505
if (previousHealth .equals (currentHealth ) == false ) {
506
506
logger .info (
507
507
new ESLogMessage ("Cluster health status changed from [{}] to [{}] (reason: [{}])." ).argAndField (
@@ -513,6 +513,40 @@ private static void logClusterHealthStateChange(
513
513
}
514
514
}
515
515
516
+ public static ClusterHealthStatus getHealthStatus (final ClusterState clusterState ) {
517
+ if (clusterState .blocks ().hasGlobalBlockWithStatus (RestStatus .SERVICE_UNAVAILABLE )) {
518
+ return ClusterHealthStatus .RED ;
519
+ }
520
+
521
+ ClusterHealthStatus computeStatus = ClusterHealthStatus .GREEN ;
522
+ for (String index : clusterState .metadata ().getConcreteAllIndices ()) {
523
+ IndexRoutingTable indexRoutingTable = clusterState .routingTable ().index (index );
524
+ if (indexRoutingTable == null ) {
525
+ continue ;
526
+ }
527
+ if (indexRoutingTable .allShardsActive ()) {
528
+ // GREEN index
529
+ continue ;
530
+ }
531
+
532
+ for (int i = 0 ; i < indexRoutingTable .size (); i ++) {
533
+ IndexShardRoutingTable indexShardRoutingTable = indexRoutingTable .shard (i );
534
+ ShardRouting primary = indexShardRoutingTable .primaryShard ();
535
+ if (primary .active ()) {
536
+ // index has inactive replicas
537
+ computeStatus = ClusterHealthStatus .YELLOW ;
538
+ continue ;
539
+ }
540
+ computeStatus = getInactivePrimaryHealth (primary );
541
+ if (computeStatus == ClusterHealthStatus .RED ) {
542
+ logger .debug ("One of inactive primary shard {} causes cluster state RED." , primary .shardId ());
543
+ return ClusterHealthStatus .RED ;
544
+ }
545
+ }
546
+ }
547
+ return computeStatus ;
548
+ }
549
+
516
550
private static boolean hasDeadNodes (RoutingAllocation allocation ) {
517
551
for (RoutingNode routingNode : allocation .routingNodes ()) {
518
552
if (allocation .nodes ().getDataNodes ().containsKey (routingNode .nodeId ()) == false ) {
0 commit comments