Skip to content

Commit c484c66

Browse files
authored
Remove index routing table of closed indices in mixed versions clusters (#38955)
This pull request removes the legacy way of closing indices (aka "direct close") in mixed versions clusters, since this backward compatibility logic is not required anymore on master/8.0.0. It also changes the closing logic so that routing tables of closed indices are removed when the cluster contains a node in version < 8.0. Relates #33888
1 parent 00f1828 commit c484c66

File tree

2 files changed

+66
-37
lines changed

2 files changed

+66
-37
lines changed

server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateService.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,6 @@ static ClusterState addIndexClosedBlocks(final Index[] indices, final Map<Index,
223223
// Check if index closing conflicts with any running snapshots
224224
SnapshotsService.checkIndexClosing(currentState, indicesToClose);
225225

226-
// If the cluster is in a mixed version that does not support the shard close action,
227-
// we use the previous way to close indices and directly close them without sanity checks
228-
final boolean useDirectClose = currentState.nodes().getMinNodeVersion().before(Version.V_6_7_0);
229-
230226
final ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks());
231227
final RoutingTable.Builder routingTable = RoutingTable.builder(currentState.routingTable());
232228

@@ -244,19 +240,11 @@ static ClusterState addIndexClosedBlocks(final Index[] indices, final Map<Index,
244240
}
245241
}
246242
}
247-
if (useDirectClose) {
248-
logger.debug("closing index {} directly", index);
249-
metadata.put(IndexMetaData.builder(indexToClose).state(IndexMetaData.State.CLOSE)); // increment version?
250-
blocks.removeIndexBlockWithId(index.getName(), INDEX_CLOSED_BLOCK_ID);
251-
routingTable.remove(index.getName());
252-
indexBlock = INDEX_CLOSED_BLOCK;
253-
} else {
254-
if (indexBlock == null) {
255-
// Create a new index closed block
256-
indexBlock = createIndexClosingBlock();
257-
}
258-
assert Strings.hasLength(indexBlock.uuid()) : "Closing block should have a UUID";
243+
if (indexBlock == null) {
244+
// Create a new index closed block
245+
indexBlock = createIndexClosingBlock();
259246
}
247+
assert Strings.hasLength(indexBlock.uuid()) : "Closing block should have a UUID";
260248
blocks.addIndexBlock(index.getName(), indexBlock);
261249
blockedIndices.put(index, indexBlock);
262250
}
@@ -384,6 +372,11 @@ private void sendVerifyShardBeforeCloseRequest(final IndexShardRoutingTable shar
384372
static ClusterState closeRoutingTable(final ClusterState currentState,
385373
final Map<Index, ClusterBlock> blockedIndices,
386374
final Map<Index, AcknowledgedResponse> results) {
375+
376+
// Remove the index routing table of closed indices if the cluster is in a mixed version
377+
// that does not support the replication of closed indices
378+
final boolean removeRoutingTable = currentState.nodes().getMinNodeVersion().before(Version.V_8_0_0);
379+
387380
final MetaData.Builder metadata = MetaData.builder(currentState.metaData());
388381
final ClusterBlocks.Builder blocks = ClusterBlocks.builder().blocks(currentState.blocks());
389382
final RoutingTable.Builder routingTable = RoutingTable.builder(currentState.routingTable());
@@ -413,7 +406,11 @@ static ClusterState closeRoutingTable(final ClusterState currentState,
413406
metadata.put(IndexMetaData.builder(indexMetaData).state(IndexMetaData.State.CLOSE));
414407
blocks.removeIndexBlockWithId(index.getName(), INDEX_CLOSED_BLOCK_ID);
415408
blocks.addIndexBlock(index.getName(), INDEX_CLOSED_BLOCK);
416-
routingTable.addAsFromOpenToClose(metadata.getSafe(index));
409+
if (removeRoutingTable) {
410+
routingTable.remove(index.getName());
411+
} else {
412+
routingTable.addAsFromOpenToClose(metadata.getSafe(index));
413+
}
417414
closedIndices.add(index.getName());
418415
} catch (final IndexNotFoundException e) {
419416
logger.debug("index {} has been deleted since it was blocked before closing, ignoring", index);

server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateServiceTests.java

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,57 @@ public void testCloseRoutingTable() {
115115
}
116116
}
117117

118+
public void testCloseRoutingTableRemovesRoutingTable() {
119+
final Set<Index> nonBlockedIndices = new HashSet<>();
120+
final Map<Index, ClusterBlock> blockedIndices = new HashMap<>();
121+
final Map<Index, AcknowledgedResponse> results = new HashMap<>();
122+
final ClusterBlock closingBlock = MetaDataIndexStateService.createIndexClosingBlock();
123+
124+
ClusterState state = ClusterState.builder(new ClusterName("testCloseRoutingTableRemovesRoutingTable")).build();
125+
for (int i = 0; i < randomIntBetween(1, 25); i++) {
126+
final String indexName = "index-" + i;
127+
128+
if (randomBoolean()) {
129+
state = addOpenedIndex(indexName, randomIntBetween(1, 5), randomIntBetween(0, 5), state);
130+
nonBlockedIndices.add(state.metaData().index(indexName).getIndex());
131+
} else {
132+
state = addBlockedIndex(indexName, randomIntBetween(1, 5), randomIntBetween(0, 5), state, closingBlock);
133+
blockedIndices.put(state.metaData().index(indexName).getIndex(), closingBlock);
134+
results.put(state.metaData().index(indexName).getIndex(), new AcknowledgedResponse(randomBoolean()));
135+
}
136+
}
137+
138+
state = ClusterState.builder(state)
139+
.nodes(DiscoveryNodes.builder(state.nodes())
140+
.add(new DiscoveryNode("old_node", buildNewFakeTransportAddress(), emptyMap(),
141+
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())), Version.V_7_1_0))
142+
.add(new DiscoveryNode("new_node", buildNewFakeTransportAddress(), emptyMap(),
143+
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())), Version.V_8_0_0)))
144+
.build();
145+
146+
state = MetaDataIndexStateService.closeRoutingTable(state, blockedIndices, results);
147+
assertThat(state.metaData().indices().size(), equalTo(nonBlockedIndices.size() + blockedIndices.size()));
148+
149+
for (Index nonBlockedIndex : nonBlockedIndices) {
150+
assertIsOpened(nonBlockedIndex.getName(), state);
151+
assertThat(state.blocks().hasIndexBlockWithId(nonBlockedIndex.getName(), INDEX_CLOSED_BLOCK_ID), is(false));
152+
}
153+
for (Index blockedIndex : blockedIndices.keySet()) {
154+
if (results.get(blockedIndex).isAcknowledged()) {
155+
assertThat(state.metaData().index(blockedIndex).getState(), is(IndexMetaData.State.CLOSE));
156+
assertThat(state.blocks().hasIndexBlock(blockedIndex.getName(), MetaDataIndexStateService.INDEX_CLOSED_BLOCK), is(true));
157+
assertThat("Index must have only 1 block with [id=" + MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID + "]",
158+
state.blocks().indices().getOrDefault(blockedIndex.getName(), emptySet()).stream()
159+
.filter(clusterBlock -> clusterBlock.id() == MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID).count(), equalTo(1L));
160+
assertThat("Index routing table should have been removed when closing the index on mixed cluster version",
161+
state.routingTable().index(blockedIndex), nullValue());
162+
} else {
163+
assertIsOpened(blockedIndex.getName(), state);
164+
assertThat(state.blocks().hasIndexBlock(blockedIndex.getName(), closingBlock), is(true));
165+
}
166+
}
167+
}
168+
118169
public void testAddIndexClosedBlocks() {
119170
final ClusterState initialState = ClusterState.builder(new ClusterName("testAddIndexClosedBlocks")).build();
120171
{
@@ -191,14 +242,6 @@ public void testAddIndexClosedBlocks() {
191242
ClusterState state = addOpenedIndex("index-1", randomIntBetween(1, 3), randomIntBetween(0, 3), initialState);
192243
state = addOpenedIndex("index-2", randomIntBetween(1, 3), randomIntBetween(0, 3), state);
193244
state = addOpenedIndex("index-3", randomIntBetween(1, 3), randomIntBetween(0, 3), state);
194-
final boolean mixedVersions = randomBoolean();
195-
if (mixedVersions) {
196-
state = ClusterState.builder(state)
197-
.nodes(DiscoveryNodes.builder(state.nodes())
198-
.add(new DiscoveryNode("old_node", buildNewFakeTransportAddress(), emptyMap(),
199-
new HashSet<>(Arrays.asList(DiscoveryNode.Role.values())), Version.V_6_0_0)))
200-
.build();
201-
}
202245

203246
Index index1 = state.metaData().index("index-1").getIndex();
204247
Index index2 = state.metaData().index("index-2").getIndex();
@@ -210,18 +253,7 @@ public void testAddIndexClosedBlocks() {
210253

211254
for (Index index : indices) {
212255
assertTrue(blockedIndices.containsKey(index));
213-
if (mixedVersions) {
214-
assertThat(updatedState.metaData().index(index).getState(), is(IndexMetaData.State.CLOSE));
215-
assertTrue(updatedState.blocks().hasIndexBlock(index.getName(), MetaDataIndexStateService.INDEX_CLOSED_BLOCK));
216-
assertThat("Index " + index + " must have only 1 block with id=" + MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID,
217-
updatedState.blocks().indices().getOrDefault(index.getName(), emptySet()).stream().filter(clusterBlock ->
218-
clusterBlock.id() == MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID).count(), equalTo(1L));
219-
220-
final IndexRoutingTable indexRoutingTable = updatedState.routingTable().index(index);
221-
assertThat(indexRoutingTable, nullValue());
222-
} else {
223-
assertHasBlock(index.getName(), updatedState, blockedIndices.get(index));
224-
}
256+
assertHasBlock(index.getName(), updatedState, blockedIndices.get(index));
225257
}
226258
}
227259
}

0 commit comments

Comments
 (0)