/** * returns true if this routing has the same allocation ID as another. * <p> * Note: if both shard routing has a null as their {@link #allocationId()}, this method returns false as the routing describe * no allocation at all.. **/ public boolean isSameAllocation(ShardRouting other) { boolean b = this.allocationId != null && other.allocationId != null && this.allocationId.getId().equals(other.allocationId.getId()); assert b == false || this.currentNodeId.equals(other.currentNodeId) : "ShardRoutings have the same allocation id but not the same node. This [" + this + "], other [" + other + "]"; return b; }
@Nullable public ShardRouting getByAllocationId(ShardId shardId, String allocationId) { final List<ShardRouting> replicaSet = assignedShards.get(shardId); if (replicaSet == null) { return null; } for (ShardRouting shardRouting : replicaSet) { if (shardRouting.allocationId().getId().equals(allocationId)) { return shardRouting; } } return null; }
@Override public void shardStarted(ShardRouting initializingShard, ShardRouting startedShard) { assert Objects.equals(initializingShard.allocationId().getId(), startedShard.allocationId().getId()) : "initializingShard.allocationId [" + initializingShard.allocationId().getId() + "] and startedShard.allocationId [" + startedShard.allocationId().getId() + "] have to have the same"; Updates updates = changes(startedShard.shardId()); updates.addedAllocationIds.add(startedShard.allocationId().getId()); if (startedShard.primary() // started shard has to have null recoverySource; have to pick up recoverySource from its initializing state && (initializingShard.recoverySource() == RecoverySource.ExistingStoreRecoverySource.FORCE_STALE_PRIMARY_INSTANCE)) { updates.removedAllocationIds.add(RecoverySource.ExistingStoreRecoverySource.FORCED_ALLOCATION_ID); } }
/** * Creates a new allocation id representing a cancelled relocation. * <p> * Note that this is expected to be called on the allocation id * of the *source* shard */ public static AllocationId cancelRelocation(AllocationId allocationId) { assert allocationId.getRelocationId() != null; return new AllocationId(allocationId.getId(), null); }
/** * Creates a new allocation id finalizing a relocation. * <p> * Note that this is expected to be called on the allocation id * of the *target* shard and thus it only needs to clear the relocating id. */ public static AllocationId finishRelocation(AllocationId allocationId) { assert allocationId.getRelocationId() != null; return new AllocationId(allocationId.getId(), null); }
/** returns true if the routing is the relocation target of the given routing */ public boolean isRelocationTargetOf(ShardRouting other) { boolean b = this.allocationId != null && other.allocationId != null && this.state == ShardRoutingState.INITIALIZING && this.allocationId.getId().equals(other.allocationId.getRelocationId()); assert b == false || other.state == ShardRoutingState.RELOCATING : "ShardRouting is a relocation target but the source shard state isn't relocating. This [" + this + "], other [" + other + "]"; assert b == false || other.allocationId.getId().equals(this.allocationId.getRelocationId()) : "ShardRouting is a relocation target but the source id isn't equal to source's allocationId.getRelocationId." + " This [" + this + "], other [" + other + "]"; assert b == false || other.currentNodeId().equals(this.relocatingNodeId) : "ShardRouting is a relocation target but source current node id isn't equal to target relocating node." + " This [" + this + "], other [" + other + "]"; assert b == false || this.currentNodeId().equals(other.relocatingNodeId) : "ShardRouting is a relocation target but current node id isn't equal to source relocating node." + " This [" + this + "], other [" + other + "]"; assert b == false || this.shardId.equals(other.shardId) : "ShardRouting is a relocation target but both indexRoutings are not of the same shard id." + " This [" + this + "], other [" + other + "]"; assert b == false || this.primary == other.primary : "ShardRouting is a relocation target but primary flag is different." + " This [" + this + "], target [" + other + "]"; return b; }
/** returns true if the routing is the relocation source for the given routing */ public boolean isRelocationSourceOf(ShardRouting other) { boolean b = this.allocationId != null && other.allocationId != null && other.state == ShardRoutingState.INITIALIZING && other.allocationId.getId().equals(this.allocationId.getRelocationId()); assert b == false || this.state == ShardRoutingState.RELOCATING : "ShardRouting is a relocation source but shard state isn't relocating. This [" + this + "], other [" + other + "]"; assert b == false || this.allocationId.getId().equals(other.allocationId.getRelocationId()) : "ShardRouting is a relocation source but the allocation id isn't equal to other.allocationId.getRelocationId." + " This [" + this + "], other [" + other + "]"; assert b == false || this.currentNodeId().equals(other.relocatingNodeId) : "ShardRouting is a relocation source but current node isn't equal to other's relocating node." + " This [" + this + "], other [" + other + "]"; assert b == false || other.currentNodeId().equals(this.relocatingNodeId) : "ShardRouting is a relocation source but relocating node isn't equal to other's current node." + " This [" + this + "], other [" + other + "]"; assert b == false || this.shardId.equals(other.shardId) : "ShardRouting is a relocation source but both indexRoutings are not of the same shard." + " This [" + this + "], target [" + other + "]"; assert b == false || this.primary == other.primary : "ShardRouting is a relocation source but primary flag is different. This [" + this + "], target [" + other + "]"; return b; }
/** * Creates a new allocation id for the target initializing shard that is the result * of a relocation. */ public static AllocationId newTargetRelocation(AllocationId allocationId) { assert allocationId.getRelocationId() != null; return new AllocationId(allocationId.getRelocationId(), 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; }
/** * Creates a new allocation id for a shard that moves to be relocated, populating * the transient holder for relocationId. */ public static AllocationId newRelocation(AllocationId allocationId) { assert allocationId.getRelocationId() == null; return new AllocationId(allocationId.getId(), UUIDs.randomBase64UUID()); }
@Override public void initializedReplicaReinitialized(ShardRouting oldReplica, ShardRouting reinitializedReplica) { assert oldReplica.initializing() && oldReplica.primary() == false : "expected initializing replica shard " + oldReplica; assert reinitializedReplica.initializing() && reinitializedReplica.primary() == false : "expected reinitialized replica shard " + reinitializedReplica; assert oldReplica.allocationId().getId().equals(reinitializedReplica.allocationId().getId()) == false : "expected allocation id to change for reinitialized replica shard (old: " + oldReplica + " new: " + reinitializedReplica + ")"; setChanged(); }
/** * Remove allocation id of this shard from the set of in-sync shard copies */ void removeAllocationId(ShardRouting shardRouting) { if (shardRouting.active()) { changes(shardRouting.shardId()).removedAllocationIds.add(shardRouting.allocationId().getId()); } }
@Override public void onResponse(ReplicaResponse response) { successfulShards.incrementAndGet(); try { primary.updateLocalCheckpointForShard(shard.allocationId().getId(), response.localCheckpoint()); primary.updateGlobalCheckpointForShard(shard.allocationId().getId(), response.globalCheckpoint()); } catch (final AlreadyClosedException e) { // okay, the index was deleted or this shard was never activated after a relocation; fall through and finish normally } catch (final Exception e) { // fail the primary but fall through and let the rest of operation processing complete final String message = String.format(Locale.ROOT, "primary failed updating local checkpoint for replica %s", shard); primary.failShard(message, e); } decPendingAndFinishIfNeeded(); }
@Override public void failShardIfNeeded(ShardRouting replica, String message, Exception exception, Runnable onSuccess, Consumer<Exception> onPrimaryDemoted, Consumer<Exception> onIgnoredFailure) { shardStateAction.remoteShardFailed(replica.shardId(), replica.allocationId().getId(), primaryTerm, false, message, exception, createShardActionListener(onSuccess, onPrimaryDemoted, onIgnoredFailure)); } }
public void shardStarted(final ShardRouting shardRouting, final String message, Listener listener, ClusterState currentState) { StartedShardEntry shardEntry = new StartedShardEntry(shardRouting.shardId(), shardRouting.allocationId().getId(), message); sendShardAction(SHARD_STARTED_ACTION_NAME, currentState, shardEntry, listener); }
/** * Send a shard failed request to the master node to update the cluster state when a shard on the local node failed. */ public void localShardFailed(final ShardRouting shardRouting, final String message, @Nullable final Exception failure, Listener listener, final ClusterState currentState) { FailedShardEntry shardEntry = new FailedShardEntry(shardRouting.shardId(), shardRouting.allocationId().getId(), 0L, message, failure, true); sendShardAction(SHARD_FAILED_ACTION_NAME, currentState, shardEntry, listener); }
private EngineConfig newEngineConfig() { Sort indexSort = indexSortSupplier.get(); return new EngineConfig(shardId, shardRouting.allocationId().getId(), threadPool, indexSettings, warmer, store, indexSettings.getMergePolicy(), mapperService.indexAnalyzer(), similarityService.similarity(mapperService), codecService, shardEventListener, indexCache.query(), cachingPolicy, translogConfig, IndexingMemoryController.SHARD_INACTIVE_TIME_SETTING.get(indexSettings.getSettings()), Collections.singletonList(refreshListeners), Collections.singletonList(new RefreshMetricUpdater(refreshMetric)), indexSort, circuitBreakerService, replicationTracker, () -> operationPrimaryTerm, tombstoneDocSupplier()); }
protected void newAllocationId(Environment environment, ShardPath shardPath, Terminal terminal) throws IOException { final Path shardStatePath = shardPath.getShardStatePath(); final ShardStateMetaData shardStateMetaData = ShardStateMetaData.FORMAT.loadLatestState(logger, namedXContentRegistry, shardStatePath); if (shardStateMetaData == null) { throw new ElasticsearchException("No shard state meta data at " + shardStatePath); } final AllocationId newAllocationId = AllocationId.newInitializing(); terminal.println("Changing allocation id " + shardStateMetaData.allocationId.getId() + " to " + newAllocationId.getId()); final ShardStateMetaData newShardStateMetaData = new ShardStateMetaData(shardStateMetaData.primary, shardStateMetaData.indexUUID, newAllocationId); ShardStateMetaData.FORMAT.write(newShardStateMetaData, shardStatePath); terminal.println(""); terminal.println("You should run the following command to allocate this shard:"); printRerouteCommand(shardPath, terminal, true); }
private void applyStartedShards(RoutingAllocation routingAllocation, List<ShardRouting> startedShardEntries) { assert startedShardEntries.isEmpty() == false : "non-empty list of started shard entries expected"; RoutingNodes routingNodes = routingAllocation.routingNodes(); for (ShardRouting startedShard : startedShardEntries) { assert startedShard.initializing() : "only initializing shards can be started"; assert routingAllocation.metaData().index(startedShard.shardId().getIndex()) != null : "shard started for unknown index (shard entry: " + startedShard + ")"; assert startedShard == routingNodes.getByAllocationId(startedShard.shardId(), startedShard.allocationId().getId()) : "shard routing to start does not exist in routing table, expected: " + startedShard + " but was: " + routingNodes.getByAllocationId(startedShard.shardId(), startedShard.allocationId().getId()); routingNodes.startShard(logger, startedShard, routingAllocation.changes()); } }
/** * Updates the known allocation IDs and the local checkpoints for the corresponding allocations from a primary relocation source. * * @param primaryContext the sequence number context */ public void activateWithPrimaryContext(final ReplicationTracker.PrimaryContext primaryContext) { assert shardRouting.primary() && shardRouting.isRelocationTarget() : "only primary relocation target can update allocation IDs from primary context: " + shardRouting; assert primaryContext.getCheckpointStates().containsKey(routingEntry().allocationId().getId()) && getLocalCheckpoint() == primaryContext.getCheckpointStates().get(routingEntry().allocationId().getId()).getLocalCheckpoint(); synchronized (mutex) { replicationTracker.activateWithPrimaryContext(primaryContext); // make changes to primaryMode flag only under mutex if (getMaxSeqNoOfUpdatesOrDeletes() == UNASSIGNED_SEQ_NO) { // If the old primary was on an old version that did not replicate the msu, // we need to bootstrap it manually from its local history. assert indexSettings.getIndexVersionCreated().before(Version.V_6_5_0); getEngine().advanceMaxSeqNoOfUpdatesOrDeletes(seqNoStats().getMaxSeqNo()); } } }