/** * Returns a shard routing representing the target shard. * The target shard routing will be the INITIALIZING state and have relocatingNodeId set to the * source node. */ public ShardRouting getTargetRelocatingShard() { assert relocating(); return targetRelocatingShard; }
static boolean distinctNodes(List<ShardRouting> shards) { Set<String> nodes = new HashSet<>(); for (ShardRouting shard : shards) { if (shard.assignedToNode()) { if (nodes.add(shard.currentNodeId()) == false) { return false; } if (shard.relocating()) { if (nodes.add(shard.relocatingNodeId()) == false) { return false; } } } } return true; }
/** * Returns the size of all shards that are currently being relocated to * the node, but may not be finished transferring yet. * * If subtractShardsMovingAway is true then the size of shards moving away is subtracted from the total size of all shards */ static long sizeOfRelocatingShards(RoutingNode node, RoutingAllocation allocation, boolean subtractShardsMovingAway, String dataPath) { ClusterInfo clusterInfo = allocation.clusterInfo(); long totalSize = 0; for (ShardRouting routing : node.shardsWithState(ShardRoutingState.RELOCATING, ShardRoutingState.INITIALIZING)) { String actualPath = clusterInfo.getDataPath(routing); if (dataPath.equals(actualPath)) { if (routing.initializing() && routing.relocatingNodeId() != null) { totalSize += getExpectedShardSize(routing, allocation, 0); } else if (subtractShardsMovingAway && routing.relocating()) { totalSize -= getExpectedShardSize(routing, allocation, 0); } } } return totalSize; }
/** * Returns <code>true</code> iff the this shard is currently * {@link ShardRoutingState#STARTED started} or * {@link ShardRoutingState#RELOCATING relocating} to another node. * Otherwise <code>false</code> */ public boolean active() { return started() || relocating(); }
public static ClusterAllocationExplanation explainShard(ShardRouting shardRouting, RoutingAllocation allocation, ClusterInfo clusterInfo, boolean includeYesDecisions, GatewayAllocator gatewayAllocator, ShardsAllocator shardAllocator) { allocation.setDebugMode(includeYesDecisions ? DebugMode.ON : DebugMode.EXCLUDE_YES_DECISIONS); ShardAllocationDecision shardDecision; if (shardRouting.initializing() || shardRouting.relocating()) { shardDecision = ShardAllocationDecision.NOT_TAKEN; } else { AllocateUnassignedDecision allocateDecision = shardRouting.unassigned() ? gatewayAllocator.decideUnassignedShardAllocation(shardRouting, allocation) : AllocateUnassignedDecision.NOT_TAKEN; if (allocateDecision.isDecisionTaken() == false) { shardDecision = shardAllocator.decideShardAllocation(shardRouting, allocation); } else { shardDecision = new ShardAllocationDecision(allocateDecision, MoveDecision.NOT_TAKEN); } } return new ClusterAllocationExplanation(shardRouting, shardRouting.currentNodeId() != null ? allocation.nodes().get(shardRouting.currentNodeId()) : null, shardRouting.relocatingNodeId() != null ? allocation.nodes().get(shardRouting.relocatingNodeId()) : null, clusterInfo, shardDecision); }
@Override public void relocationCompleted(ShardRouting removedRelocationSource) { assert removedRelocationSource.relocating() : "expected relocating shard " + removedRelocationSource; setChanged(); }
/** * Cancels the give shard from the Routing nodes internal statistics and cancels * the relocation if the shard is relocating. */ private void remove(ShardRouting shard) { assert shard.unassigned() == false : "only assigned shards can be removed here (" + shard + ")"; node(shard.currentNodeId()).remove(shard); if (shard.initializing() && shard.relocatingNodeId() == null) { inactiveShardCount--; assert inactiveShardCount >= 0; if (shard.primary()) { inactivePrimaryCount--; } } else if (shard.relocating()) { shard = cancelRelocation(shard); } assignedShardsRemove(shard); if (shard.initializing()) { removeRecovery(shard); } }
private ShardsIterator allShardsSatisfyingPredicate(String[] indices, Predicate<ShardRouting> predicate, boolean includeRelocationTargets) { // use list here since we need to maintain identity across shards List<ShardRouting> shards = new ArrayList<>(); for (String index : indices) { IndexRoutingTable indexRoutingTable = index(index); if (indexRoutingTable == null) { continue; // we simply ignore indices that don't exists (make sense for operations that use it currently) } for (IndexShardRoutingTable indexShardRoutingTable : indexRoutingTable) { for (ShardRouting shardRouting : indexShardRoutingTable) { if (predicate.test(shardRouting)) { shards.add(shardRouting); if (includeRelocationTargets && shardRouting.relocating()) { shards.add(shardRouting.getTargetRelocatingShard()); } } } } } return new PlainShardsIterator(shards); }
private RecoveryResponse recover(final StartRecoveryRequest request) throws IOException { final IndexService indexService = indicesService.indexServiceSafe(request.shardId().getIndex()); final IndexShard shard = indexService.getShard(request.shardId().id()); final ShardRouting routingEntry = shard.routingEntry(); if (routingEntry.primary() == false || routingEntry.active() == false) { throw new DelayRecoveryException("source shard [" + routingEntry + "] is not an active primary"); } if (request.isPrimaryRelocation() && (routingEntry.relocating() == false || routingEntry.relocatingNodeId().equals(request.targetNode().getId()) == false)) { logger.debug("delaying recovery of {} as source shard is not marked yet as relocating to {}", request.shardId(), request.targetNode()); throw new DelayRecoveryException("source shard is not marked yet as relocating to [" + request.targetNode() + "]"); } RecoverySourceHandler handler = ongoingRecoveries.addNewRecovery(request, shard); logger.trace("[{}][{}] starting recovery to {}", request.shardId().getIndex().getName(), request.shardId().id(), request.targetNode()); try { return handler.recoverToTarget(); } finally { ongoingRecoveries.remove(shard, handler); } }
private void verifyRelocatingState() { if (state != IndexShardState.STARTED) { throw new IndexShardNotStartedException(shardId, state); } /* * If the master cancelled recovery, the target will be removed and the recovery will be cancelled. However, it is still possible * that we concurrently end up here and therefore have to protect that we do not mark the shard as relocated when its shard routing * says otherwise. */ if (shardRouting.relocating() == false) { throw new IllegalIndexShardStateException(shardId, IndexShardState.STARTED, ": shard is no longer relocating " + shardRouting); } if (primaryReplicaResyncInProgress.get()) { throw new IllegalIndexShardStateException(shardId, IndexShardState.STARTED, ": primary relocation is forbidden while primary-replica resync is in progress " + shardRouting); } }
private GroupShardsIterator<ShardIterator> allSatisfyingPredicateShardsGrouped(String[] indices, boolean includeEmpty, boolean includeRelocationTargets, Predicate<ShardRouting> predicate) { // use list here since we need to maintain identity across shards ArrayList<ShardIterator> set = new ArrayList<>(); for (String index : indices) { IndexRoutingTable indexRoutingTable = index(index); if (indexRoutingTable == null) { continue; // we simply ignore indices that don't exists (make sense for operations that use it currently) } for (IndexShardRoutingTable indexShardRoutingTable : indexRoutingTable) { for (ShardRouting shardRouting : indexShardRoutingTable) { if (predicate.test(shardRouting)) { set.add(shardRouting.shardsIt()); if (includeRelocationTargets && shardRouting.relocating()) { set.add(new PlainShardIterator(shardRouting.shardId(), Collections.singletonList(shardRouting.getTargetRelocatingShard()))); } } else if (includeEmpty) { // we need this for counting properly, just make it an empty one set.add(new PlainShardIterator(shardRouting.shardId(), Collections.<ShardRouting>emptyList())); } } } } return new GroupShardsIterator<>(set); }
skippedShards.add(shard); if (shard.relocating()) { ShardRouting relocationTarget = shard.getTargetRelocatingShard(); if (trackedAllocationIds.contains(relocationTarget.allocationId().getId())) {
@Nullable public ShardRouting getByAllocationId(String allocationId) { for (ShardRouting shardRouting : assignedShards()) { if (shardRouting.allocationId().getId().equals(allocationId)) { return shardRouting; } if (shardRouting.relocating()) { if (shardRouting.getTargetRelocatingShard().allocationId().getId().equals(allocationId)) { return shardRouting.getTargetRelocatingShard(); } } } return null; }
@Override public Decision canAllocate(RoutingNode node, RoutingAllocation allocation) { // Only checks the node-level limit, not the index-level // Capture the limit here in case it changes during this method's // execution final int clusterShardLimit = this.clusterShardLimit; if (clusterShardLimit <= 0) { return allocation.decision(Decision.YES, NAME, "total shard limits are disabled: [cluster: %d] <= 0", clusterShardLimit); } int nodeShardCount = 0; for (ShardRouting nodeShard : node) { // don't count relocating shards... if (nodeShard.relocating()) { continue; } nodeShardCount++; } if (clusterShardLimit >= 0 && nodeShardCount >= clusterShardLimit) { return allocation.decision(Decision.NO, NAME, "too many shards [%d] allocated to this node, cluster setting [%s=%d]", nodeShardCount, CLUSTER_TOTAL_SHARDS_PER_NODE_SETTING.getKey(), clusterShardLimit); } return allocation.decision(Decision.YES, NAME, "the shard count [%d] for this node is under the cluster level node limit [%d]", nodeShardCount, clusterShardLimit); } }
.stream() .flatMap(shr -> { if (shr.relocating()) { return Stream.of(shr, shr.getTargetRelocatingShard()); } else {
for (ShardRouting nodeShard : node) { if (nodeShard.relocating()) { continue;
if (shardRouting.active()) { computeActiveShards++; if (shardRouting.relocating()) {
throw new IndexShardSnapshotFailedException(shardId, "snapshot should be performed only on primary"); if (indexShard.routingEntry().relocating()) {
shards.put(shardId, new ShardSnapshotStatus(shardRouting.primaryShard().currentNodeId())); continue; } else if (shardRouting.primaryShard().initializing() || shardRouting.primaryShard().relocating()) {
} else if (shardRouting.relocating()) { initializingShard = shardRouting.cancelRelocation() .relocate(currentNodeId, ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE)