-
Notifications
You must be signed in to change notification settings - Fork 25.3k
Omit writing index metadata for non-replicated closed indices on data-only node #47285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ad77fd9
e648954
12a7e09
d196810
800d657
55ed4fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ | |
import org.elasticsearch.cluster.metadata.IndexMetaData; | ||
import org.elasticsearch.cluster.metadata.Manifest; | ||
import org.elasticsearch.cluster.metadata.MetaData; | ||
import org.elasticsearch.cluster.metadata.MetaDataIndexStateService; | ||
import org.elasticsearch.cluster.node.DiscoveryNode; | ||
import org.elasticsearch.cluster.node.DiscoveryNodeRole; | ||
import org.elasticsearch.cluster.node.DiscoveryNodes; | ||
|
@@ -73,17 +74,6 @@ | |
|
||
public class IncrementalClusterStateWriterTests extends ESAllocationTestCase { | ||
|
||
private ClusterState noIndexClusterState(boolean masterEligible) { | ||
MetaData metaData = MetaData.builder().build(); | ||
RoutingTable routingTable = RoutingTable.builder().build(); | ||
|
||
return ClusterState.builder(org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY)) | ||
.metaData(metaData) | ||
.routingTable(routingTable) | ||
.nodes(generateDiscoveryNodes(masterEligible)) | ||
.build(); | ||
} | ||
|
||
private ClusterState clusterStateWithUnassignedIndex(IndexMetaData indexMetaData, boolean masterEligible) { | ||
MetaData metaData = MetaData.builder() | ||
.put(indexMetaData, false) | ||
|
@@ -119,7 +109,7 @@ private ClusterState clusterStateWithAssignedIndex(IndexMetaData indexMetaData, | |
.metaData(metaDataNewClusterState).version(oldClusterState.getVersion() + 1).build(); | ||
} | ||
|
||
private ClusterState clusterStateWithClosedIndex(IndexMetaData indexMetaData, boolean masterEligible) { | ||
private ClusterState clusterStateWithNonReplicatedClosedIndex(IndexMetaData indexMetaData, boolean masterEligible) { | ||
ClusterState oldClusterState = clusterStateWithAssignedIndex(indexMetaData, masterEligible); | ||
|
||
MetaData metaDataNewClusterState = MetaData.builder() | ||
|
@@ -128,23 +118,41 @@ private ClusterState clusterStateWithClosedIndex(IndexMetaData indexMetaData, bo | |
.version(oldClusterState.metaData().version() + 1) | ||
.build(); | ||
RoutingTable routingTable = RoutingTable.builder() | ||
.addAsNew(metaDataNewClusterState.index("test")) | ||
.addAsRecovery(metaDataNewClusterState.index("test")) | ||
.build(); | ||
|
||
return ClusterState.builder(oldClusterState).routingTable(routingTable) | ||
.metaData(metaDataNewClusterState).version(oldClusterState.getVersion() + 1).build(); | ||
} | ||
|
||
private ClusterState clusterStateWithJustOpenedIndex(IndexMetaData indexMetaData, boolean masterEligible) { | ||
ClusterState oldClusterState = clusterStateWithClosedIndex(indexMetaData, masterEligible); | ||
private ClusterState clusterStateWithReplicatedClosedIndex(IndexMetaData indexMetaData, boolean masterEligible, boolean assigned) { | ||
ClusterState oldClusterState = clusterStateWithAssignedIndex(indexMetaData, masterEligible); | ||
|
||
MetaData metaDataNewClusterState = MetaData.builder() | ||
.put(IndexMetaData.builder("test").settings(settings(Version.CURRENT)).state(IndexMetaData.State.OPEN) | ||
.put(IndexMetaData.builder("test").settings(settings(Version.CURRENT) | ||
.put(MetaDataIndexStateService.VERIFIED_BEFORE_CLOSE_SETTING.getKey(), true)) | ||
.state(IndexMetaData.State.CLOSE) | ||
.numberOfShards(5).numberOfReplicas(2)) | ||
.version(oldClusterState.metaData().version() + 1) | ||
.build(); | ||
RoutingTable routingTable = RoutingTable.builder() | ||
.addAsRecovery(metaDataNewClusterState.index("test")) | ||
.build(); | ||
|
||
oldClusterState = ClusterState.builder(oldClusterState).routingTable(routingTable) | ||
.metaData(metaDataNewClusterState).build(); | ||
if (assigned) { | ||
AllocationService strategy = createAllocationService(Settings.builder() | ||
.put("cluster.routing.allocation.node_concurrent_recoveries", 100) | ||
.put(ClusterRebalanceAllocationDecider.CLUSTER_ROUTING_ALLOCATION_ALLOW_REBALANCE_SETTING.getKey(), "always") | ||
.put("cluster.routing.allocation.cluster_concurrent_rebalance", 100) | ||
.put("cluster.routing.allocation.node_initial_primaries_recoveries", 100) | ||
.build()); | ||
|
||
routingTable = strategy.reroute(oldClusterState, "reroute").routingTable(); | ||
} | ||
|
||
return ClusterState.builder(oldClusterState) | ||
return ClusterState.builder(oldClusterState).routingTable(routingTable) | ||
.metaData(metaDataNewClusterState).version(oldClusterState.getVersion() + 1).build(); | ||
} | ||
|
||
|
@@ -154,14 +162,6 @@ private DiscoveryNodes.Builder generateDiscoveryNodes(boolean masterEligible) { | |
.add(newNode("master_node", MASTER_DATA_ROLES)).localNodeId("node1").masterNodeId(masterEligible ? "node1" : "master_node"); | ||
} | ||
|
||
private Set<Index> randomPrevWrittenIndices(IndexMetaData indexMetaData) { | ||
if (randomBoolean()) { | ||
return Collections.singleton(indexMetaData.getIndex()); | ||
} else { | ||
return Collections.emptySet(); | ||
} | ||
} | ||
|
||
private IndexMetaData createIndexMetaData(String name) { | ||
return IndexMetaData.builder(name). | ||
settings(settings(Version.CURRENT)). | ||
|
@@ -172,56 +172,41 @@ private IndexMetaData createIndexMetaData(String name) { | |
|
||
public void testGetRelevantIndicesWithUnassignedShardsOnMasterEligibleNode() { | ||
IndexMetaData indexMetaData = createIndexMetaData("test"); | ||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices( | ||
clusterStateWithUnassignedIndex(indexMetaData, true), | ||
noIndexClusterState(true), | ||
randomPrevWrittenIndices(indexMetaData)); | ||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices(clusterStateWithUnassignedIndex(indexMetaData, true)); | ||
assertThat(indices.size(), equalTo(1)); | ||
} | ||
|
||
public void testGetRelevantIndicesWithUnassignedShardsOnDataOnlyNode() { | ||
IndexMetaData indexMetaData = createIndexMetaData("test"); | ||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices( | ||
clusterStateWithUnassignedIndex(indexMetaData, false), | ||
noIndexClusterState(false), | ||
randomPrevWrittenIndices(indexMetaData)); | ||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices(clusterStateWithUnassignedIndex(indexMetaData, false)); | ||
assertThat(indices.size(), equalTo(0)); | ||
} | ||
|
||
public void testGetRelevantIndicesWithAssignedShards() { | ||
IndexMetaData indexMetaData = createIndexMetaData("test"); | ||
boolean masterEligible = randomBoolean(); | ||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices( | ||
clusterStateWithAssignedIndex(indexMetaData, masterEligible), | ||
clusterStateWithUnassignedIndex(indexMetaData, masterEligible), | ||
randomPrevWrittenIndices(indexMetaData)); | ||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices(clusterStateWithAssignedIndex(indexMetaData, masterEligible)); | ||
assertThat(indices.size(), equalTo(1)); | ||
} | ||
|
||
public void testGetRelevantIndicesForClosedPrevWrittenIndexOnDataOnlyNode() { | ||
public void testGetRelevantIndicesForNonReplicatedClosedIndexOnDataOnlyNode() { | ||
IndexMetaData indexMetaData = createIndexMetaData("test"); | ||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices( | ||
clusterStateWithClosedIndex(indexMetaData, false), | ||
clusterStateWithAssignedIndex(indexMetaData, false), | ||
Collections.singleton(indexMetaData.getIndex())); | ||
assertThat(indices.size(), equalTo(1)); | ||
clusterStateWithNonReplicatedClosedIndex(indexMetaData, false)); | ||
assertThat(indices.size(), equalTo(0)); | ||
} | ||
|
||
public void testGetRelevantIndicesForClosedPrevNotWrittenIndexOnDataOnlyNode() { | ||
public void testGetRelevantIndicesForReplicatedClosedButUnassignedIndexOnDataOnlyNode() { | ||
IndexMetaData indexMetaData = createIndexMetaData("test"); | ||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices( | ||
clusterStateWithJustOpenedIndex(indexMetaData, false), | ||
clusterStateWithClosedIndex(indexMetaData, false), | ||
Collections.emptySet()); | ||
clusterStateWithReplicatedClosedIndex(indexMetaData, false, false)); | ||
assertThat(indices.size(), equalTo(0)); | ||
} | ||
|
||
public void testGetRelevantIndicesForWasClosedPrevWrittenIndexOnDataOnlyNode() { | ||
public void testGetRelevantIndicesForReplicatedClosedAndAssignedIndexOnDataOnlyNode() { | ||
IndexMetaData indexMetaData = createIndexMetaData("test"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test is now a duplicate of the previous one, and I think that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. makes sense, updated |
||
Set<Index> indices = IncrementalClusterStateWriter.getRelevantIndices( | ||
clusterStateWithJustOpenedIndex(indexMetaData, false), | ||
clusterStateWithClosedIndex(indexMetaData, false), | ||
Collections.singleton(indexMetaData.getIndex())); | ||
clusterStateWithReplicatedClosedIndex(indexMetaData, false, true)); | ||
assertThat(indices.size(), equalTo(1)); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -432,6 +432,31 @@ public Settings onNodeStopped(String nodeName) throws Exception { | |
} | ||
} | ||
|
||
/** | ||
* Test for https://github.com/elastic/elasticsearch/issues/47276 which checks that the persisted metadata on a data node does not | ||
* become inconsistent when using replicated closed indices. | ||
*/ | ||
public void testRelocatedClosedIndexIssue() throws Exception { | ||
final String indexName = "closed-index"; | ||
final List<String> dataNodes = internalCluster().startDataOnlyNodes(2); | ||
// allocate shard to first data node | ||
createIndex(indexName, Settings.builder() | ||
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) | ||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) | ||
.put("index.routing.allocation.include._name", dataNodes.get(0)) | ||
.build()); | ||
indexRandom(randomBoolean(), randomBoolean(), randomBoolean(), IntStream.range(0, randomIntBetween(0, 50)) | ||
.mapToObj(n -> client().prepareIndex(indexName, "_doc").setSource("num", n)).collect(toList())); | ||
assertAcked(client().admin().indices().prepareClose(indexName)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't forget the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. haha, good one :) |
||
// move single shard to second node | ||
client().admin().indices().prepareUpdateSettings(indexName).setSettings(Settings.builder() | ||
.put("index.routing.allocation.include._name", dataNodes.get(1))).get(); | ||
ensureGreen(indexName); | ||
internalCluster().fullRestart(); | ||
assertIndexIsClosed(indexName); | ||
ensureGreen(indexName); | ||
} | ||
|
||
public void testResyncPropagatePrimaryTerm() throws Exception { | ||
internalCluster().ensureAtLeastNumDataNodes(3); | ||
final String indexName = "closed_indices_promotion"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💥