/** * 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()); }
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); }
/** * Relocate the shard to another node. * * @param relocatingNodeId id of the node to relocate the shard */ public ShardRouting relocate(String relocatingNodeId, long expectedShardSize) { assert state == ShardRoutingState.STARTED : "current shard has to be started in order to be relocated " + this; return new ShardRouting(shardId, currentNodeId, relocatingNodeId, primary, ShardRoutingState.RELOCATING, recoverySource, null, AllocationId.newRelocation(allocationId), expectedShardSize); }
/** * Set the shards state to <code>STARTED</code>. The shards state must be * <code>INITIALIZING</code> or <code>RELOCATING</code>. Any relocation will be * canceled. */ public ShardRouting moveToStarted() { assert state == ShardRoutingState.INITIALIZING : "expected an initializing shard " + this; AllocationId allocationId = this.allocationId; if (allocationId.getRelocationId() != null) { // relocation target allocationId = AllocationId.finishRelocation(allocationId); } return new ShardRouting(shardId, currentNodeId, null, primary, ShardRoutingState.STARTED, null, null, allocationId, UNAVAILABLE_EXPECTED_SHARD_SIZE); }
/** 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 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; }
/** * Initializes an unassigned shard on a node. * * @param existingAllocationId allocation id to use. If null, a fresh allocation id is generated. */ public ShardRouting initialize(String nodeId, @Nullable String existingAllocationId, long expectedShardSize) { assert state == ShardRoutingState.UNASSIGNED : this; assert relocatingNodeId == null : this; final AllocationId allocationId; if (existingAllocationId == null) { allocationId = AllocationId.newInitializing(); } else { allocationId = AllocationId.newInitializing(existingAllocationId); } return new ShardRouting(shardId, nodeId, null, primary, ShardRoutingState.INITIALIZING, recoverySource, unassignedInfo, allocationId, expectedShardSize); }
private static AllocationId buildAllocationId(ShardRoutingState state) { switch (state) { case UNASSIGNED: return null; case INITIALIZING: case STARTED: return AllocationId.newInitializing(); case RELOCATING: AllocationId allocationId = AllocationId.newInitializing(); return AllocationId.newRelocation(allocationId); default: throw new IllegalStateException("illegal state"); } }
@Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ShardStateMetaData that = (ShardStateMetaData) o; if (primary != that.primary) { return false; } if (indexUUID != null ? !indexUUID.equals(that.indexUUID) : that.indexUUID != null) { return false; } if (allocationId != null ? !allocationId.equals(that.allocationId) : that.allocationId != null) { return false; } return true; }
@Override public int hashCode() { int result = (indexUUID != null ? indexUUID.hashCode() : 0); result = 31 * result + (allocationId != null ? allocationId.hashCode() : 0); result = 31 * result + (primary ? 1 : 0); return result; }
/** * Cancel relocation of a shard. The shards state must be set * to <code>RELOCATING</code>. */ public ShardRouting cancelRelocation() { assert state == ShardRoutingState.RELOCATING : this; assert assignedToNode() : this; assert relocatingNodeId != null : this; return new ShardRouting(shardId, currentNodeId, null, primary, ShardRoutingState.STARTED, recoverySource, null, AllocationId.cancelRelocation(allocationId), UNAVAILABLE_EXPECTED_SHARD_SIZE); }
/** * Creates a new allocation id for initializing allocation based on an existing id. */ public static AllocationId newInitializing(String existingAllocationId) { return new AllocationId(existingAllocationId, null); }
@Nullable private ShardRouting initializeTargetRelocatingShard() { if (state == ShardRoutingState.RELOCATING) { return new ShardRouting(shardId, relocatingNodeId, currentNodeId, primary, ShardRoutingState.INITIALIZING, PeerRecoverySource.INSTANCE, unassignedInfo, AllocationId.newTargetRelocation(allocationId), expectedShardSize); } else { return null; } }
/** * Removes relocation source of a non-primary shard. The shard state must be <code>INITIALIZING</code>. * This allows the non-primary shard to continue recovery from the primary even though its non-primary * relocation source has failed. */ public ShardRouting removeRelocationSource() { assert primary == false : this; assert state == ShardRoutingState.INITIALIZING : this; assert assignedToNode() : this; assert relocatingNodeId != null : this; return new ShardRouting(shardId, currentNodeId, null, primary, state, recoverySource, unassignedInfo, AllocationId.finishRelocation(allocationId), expectedShardSize); }
if (routing.isRelocationTarget()) { ShardRouting sourceShard = getByAllocationId(routing.shardId(), routing.allocationId().getRelocationId());
@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; }
/** 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; }
/** * Set the shards state to <code>STARTED</code>. The shards state must be * <code>INITIALIZING</code> or <code>RELOCATING</code>. Any relocation will be * canceled. */ public ShardRouting moveToStarted() { assert state == ShardRoutingState.INITIALIZING : "expected an initializing shard " + this; AllocationId allocationId = this.allocationId; if (allocationId.getRelocationId() != null) { // relocation target allocationId = AllocationId.finishRelocation(allocationId); } return new ShardRouting(shardId, currentNodeId, null, primary, ShardRoutingState.STARTED, null, null, allocationId, UNAVAILABLE_EXPECTED_SHARD_SIZE); }
/** * Reinitializes a replica shard, giving it a fresh allocation id */ public ShardRouting reinitializeReplicaShard() { assert state == ShardRoutingState.INITIALIZING : this; assert primary == false : this; assert isRelocationTarget() == false : this; return new ShardRouting(shardId, currentNodeId, null, primary, ShardRoutingState.INITIALIZING, recoverySource, unassignedInfo, AllocationId.newInitializing(), expectedShardSize); }
/** returns true if the current routing is identical to the other routing in all but meta fields, i.e., unassigned info */ public boolean equalsIgnoringMetaData(ShardRouting other) { if (primary != other.primary) { return false; } if (shardId != null ? !shardId.equals(other.shardId) : other.shardId != null) { return false; } if (currentNodeId != null ? !currentNodeId.equals(other.currentNodeId) : other.currentNodeId != null) { return false; } if (relocatingNodeId != null ? !relocatingNodeId.equals(other.relocatingNodeId) : other.relocatingNodeId != null) { return false; } if (allocationId != null ? !allocationId.equals(other.allocationId) : other.allocationId != null) { return false; } if (state != other.state) { return false; } if (recoverySource != null ? !recoverySource.equals(other.recoverySource) : other.recoverySource != null) { return false; } return true; }