Skip to content

Commit bd12ab9

Browse files
committed
Also handle case where one of the original shards is relocating when closed
1 parent be9ac06 commit bd12ab9

File tree

2 files changed

+35
-16
lines changed

2 files changed

+35
-16
lines changed

server/src/main/java/org/elasticsearch/cluster/routing/IndexRoutingTable.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,9 @@ private static List<String> getPreviousNodes(@Nullable IndexRoutingTable previou
517517
final var previousNodes = new ArrayList<String>(previousShardRoutingTable.size());
518518
previousNodes.add(primaryNodeId); // primary is recreated first, so re-use its location
519519
for (final var assignedShard : previousShardRoutingTable.assignedShards()) {
520+
if (assignedShard.initializing() && assignedShard.relocatingNodeId() != null) {
521+
continue;
522+
}
520523
final var currentNodeId = assignedShard.currentNodeId();
521524
assert currentNodeId != null;
522525
if (primaryNodeId.equals(currentNodeId) == false) {

server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.elasticsearch.cluster.metadata.IndexMetadata;
1919
import org.elasticsearch.cluster.metadata.Metadata;
2020
import org.elasticsearch.cluster.metadata.SingleNodeShutdownMetadata;
21+
import org.elasticsearch.cluster.node.DiscoveryNode;
2122
import org.elasticsearch.cluster.node.DiscoveryNodes;
2223
import org.elasticsearch.cluster.routing.RecoverySource.SnapshotRecoverySource;
2324
import org.elasticsearch.cluster.routing.UnassignedInfo.AllocationStatus;
@@ -204,38 +205,53 @@ public void testIndexClosedAndReopened() {
204205
);
205206
assertTrue(clusterState0.routingTable().index("test").allShardsActive());
206207

207-
// cluster state 1: index closed and fully unassigned
208+
// cluster state 1: perhaps start one of the shards relocating
209+
final var clusterState1 = randomBoolean()
210+
? clusterState0
211+
: allocationService.executeWithRoutingAllocation(clusterState0, "test", routingAllocation -> {
212+
final var indexShardRoutingTable = routingAllocation.routingTable().index("test").shard(0);
213+
for (DiscoveryNode node : routingAllocation.nodes()) {
214+
if (routingAllocation.routingNodes().node(node.getId()).getByShardId(indexShardRoutingTable.shardId()) == null) {
215+
routingAllocation.routingNodes()
216+
.relocateShard(indexShardRoutingTable.shard(0), node.getId(), 0L, routingAllocation.changes());
217+
return;
218+
}
219+
}
220+
throw new AssertionError("no suitable target found");
221+
});
222+
223+
// cluster state 2: index closed and fully unassigned
208224
final var metadata1 = Metadata.builder(metadata0)
209225
.put(IndexMetadata.builder(metadata0.index("test")).state(IndexMetadata.State.CLOSE))
210226
.build();
211-
final var clusterState1 = ClusterState.builder(clusterState0)
227+
final var clusterState2 = ClusterState.builder(clusterState1)
212228
.metadata(metadata1)
213-
.routingTable(RoutingTable.builder(clusterState0.routingTable()).addAsFromOpenToClose(metadata1.index("test")))
229+
.routingTable(RoutingTable.builder(clusterState1.routingTable()).addAsFromOpenToClose(metadata1.index("test")))
214230
.build();
215231

216232
assertLastAllocatedNodeIdsAssigned(
217233
UnassignedInfo.Reason.INDEX_CLOSED,
218-
clusterState0.routingTable().index("test"),
219-
clusterState1.routingTable().index("test")
234+
clusterState1.routingTable().index("test"),
235+
clusterState2.routingTable().index("test")
220236
);
221237

222-
// cluster state 2: closed index has been fully assigned
223-
final var clusterState2 = applyStartedShardsUntilNoChange(clusterState1, allocationService);
224-
assertTrue(clusterState2.routingTable().index("test").allShardsActive());
238+
// cluster state 3: closed index has been fully assigned
239+
final var clusterState3 = applyStartedShardsUntilNoChange(clusterState2, allocationService);
240+
assertTrue(clusterState3.routingTable().index("test").allShardsActive());
225241

226-
// cluster state 3: index reopened, fully unassigned again
227-
final var metadata3 = Metadata.builder(metadata0)
242+
// cluster state 4: index reopened, fully unassigned again
243+
final var metadata4 = Metadata.builder(metadata0)
228244
.put(IndexMetadata.builder(metadata1.index("test")).state(IndexMetadata.State.OPEN))
229245
.build();
230-
final var clusterState3 = ClusterState.builder(clusterState2)
231-
.metadata(metadata3)
232-
.routingTable(RoutingTable.builder(clusterState2.routingTable()).addAsFromCloseToOpen(metadata3.index("test")))
246+
final var clusterState4 = ClusterState.builder(clusterState3)
247+
.metadata(metadata4)
248+
.routingTable(RoutingTable.builder(clusterState3.routingTable()).addAsFromCloseToOpen(metadata4.index("test")))
233249
.build();
234250

235251
assertLastAllocatedNodeIdsAssigned(
236252
UnassignedInfo.Reason.INDEX_REOPENED,
237-
clusterState2.routingTable().index("test"),
238-
clusterState3.routingTable().index("test")
253+
clusterState3.routingTable().index("test"),
254+
clusterState4.routingTable().index("test")
239255
);
240256
}
241257

@@ -256,7 +272,7 @@ private void assertLastAllocatedNodeIdsAssigned(
256272
final var previousNodes = previousShardRoutingTable == null
257273
? Set.<String>of()
258274
: IntStream.range(0, previousShardRoutingTable.size()).mapToObj(previousShardRoutingTable::shard).map(shard -> {
259-
assertTrue(shard.started());
275+
assertTrue(shard.started() || shard.relocating());
260276
return shard.currentNodeId();
261277
}).collect(Collectors.toSet());
262278
final var shardRoutingTable = finalRoutingTable.shard(shardId);

0 commit comments

Comments
 (0)