Skip to content

Commit c400c0e

Browse files
committed
Omit writing index metadata for non-replicated closed indices on data-only node (#47285)
Fixes a bug related to how "closed replicated indices" (introduced in 7.2) interact with the index metadata storage mechanism, which has special handling for closed indices (but incorrectly handles replicated closed indices). On non-master-eligible data nodes, it's possible for the node's manifest file (which tracks the relevant metadata state that the node should persist) to become out of sync with what's actually stored on disk, leading to an inconsistency that is then detected at startup, refusing for the node to start up. Closes #47276
1 parent b1c15a0 commit c400c0e

File tree

3 files changed

+27
-16
lines changed

3 files changed

+27
-16
lines changed

server/src/main/java/org/elasticsearch/gateway/GatewayMetaState.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -509,20 +509,6 @@ private static Set<Index> getRelevantIndicesOnDataOnlyNode(ClusterState state, C
509509
for (ShardRouting routing : newRoutingNode) {
510510
indices.add(routing.index());
511511
}
512-
// we have to check the meta data also: closed indices will not appear in the routing table, but we must still write the state if
513-
// we have it written on disk previously
514-
for (IndexMetaData indexMetaData : state.metaData()) {
515-
boolean isOrWasClosed = indexMetaData.getState().equals(IndexMetaData.State.CLOSE);
516-
// if the index is open we might still have to write the state if it just transitioned from closed to open
517-
// so we have to check for that as well.
518-
IndexMetaData previousMetaData = previousState.metaData().index(indexMetaData.getIndex());
519-
if (previousMetaData != null) {
520-
isOrWasClosed = isOrWasClosed || previousMetaData.getState().equals(IndexMetaData.State.CLOSE);
521-
}
522-
if (previouslyWrittenIndices.contains(indexMetaData.getIndex()) && isOrWasClosed) {
523-
indices.add(indexMetaData.getIndex());
524-
}
525-
}
526512
return indices;
527513
}
528514

server/src/test/java/org/elasticsearch/gateway/GatewayMetaStateTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public void testGetRelevantIndicesForClosedPrevWrittenIndexOnDataOnlyNode() {
199199
clusterStateWithClosedIndex(indexMetaData, false),
200200
clusterStateWithAssignedIndex(indexMetaData, false),
201201
Collections.singleton(indexMetaData.getIndex()));
202-
assertThat(indices.size(), equalTo(1));
202+
assertThat(indices.size(), equalTo(0));
203203
}
204204

205205
public void testGetRelevantIndicesForClosedPrevNotWrittenIndexOnDataOnlyNode() {
@@ -217,7 +217,7 @@ public void testGetRelevantIndicesForWasClosedPrevWrittenIndexOnDataOnlyNode() {
217217
clusterStateWithJustOpenedIndex(indexMetaData, false),
218218
clusterStateWithClosedIndex(indexMetaData, false),
219219
Collections.singleton(indexMetaData.getIndex()));
220-
assertThat(indices.size(), equalTo(1));
220+
assertThat(indices.size(), equalTo(0));
221221
}
222222

223223
public void testResolveStatesToBeWritten() throws WriteStateException {

server/src/test/java/org/elasticsearch/indices/state/CloseIndexIT.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,31 @@ public Settings onNodeStopped(String nodeName) throws Exception {
435435
}
436436
}
437437

438+
/**
439+
* Test for https://github.com/elastic/elasticsearch/issues/47276 which checks that the persisted metadata on a data node does not
440+
* become inconsistent when using replicated closed indices.
441+
*/
442+
public void testRelocatedClosedIndexIssue() throws Exception {
443+
final String indexName = "closed-index";
444+
final List<String> dataNodes = internalCluster().startDataOnlyNodes(2);
445+
// allocate shard to first data node
446+
createIndex(indexName, Settings.builder()
447+
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
448+
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
449+
.put("index.routing.allocation.include._name", dataNodes.get(0))
450+
.build());
451+
indexRandom(randomBoolean(), randomBoolean(), randomBoolean(), IntStream.range(0, randomIntBetween(0, 50))
452+
.mapToObj(n -> client().prepareIndex(indexName, "_doc").setSource("num", n)).collect(toList()));
453+
assertAcked(client().admin().indices().prepareClose(indexName).setWaitForActiveShards(ActiveShardCount.ALL));
454+
// move single shard to second node
455+
client().admin().indices().prepareUpdateSettings(indexName).setSettings(Settings.builder()
456+
.put("index.routing.allocation.include._name", dataNodes.get(1))).get();
457+
ensureGreen(indexName);
458+
internalCluster().fullRestart();
459+
assertIndexIsClosed(indexName);
460+
ensureGreen(indexName);
461+
}
462+
438463
public void testResyncPropagatePrimaryTerm() throws Exception {
439464
internalCluster().ensureAtLeastNumDataNodes(3);
440465
final String indexName = "closed_indices_promotion";

0 commit comments

Comments
 (0)