-
Notifications
You must be signed in to change notification settings - Fork 25.2k
ILM wait for active shards on rolled index in a separate step #50718
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 10 commits
f6290e4
fccfee5
456ba48
292a8e6
b2673bd
77364de
0a98bf0
4842f39
eb8f95f
a4615f8
115a131
0924222
bf09bbc
c33a595
6225c04
a27e1cc
a838925
9f9b842
c3f506e
7679143
3a1cd87
b838f3a
4449853
64c9f06
9322665
36e07fc
c0ecf31
f4f2c84
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 | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,68 @@ | ||||||
/* | ||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||||||
* or more contributor license agreements. Licensed under the Elastic License; | ||||||
* you may not use this file except in compliance with the Elastic License. | ||||||
*/ | ||||||
package org.elasticsearch.xpack.core.ilm; | ||||||
|
||||||
import org.elasticsearch.action.support.ActiveShardCount; | ||||||
import org.elasticsearch.cluster.ClusterState; | ||||||
import org.elasticsearch.cluster.metadata.AliasOrIndex; | ||||||
import org.elasticsearch.cluster.metadata.AliasOrIndex.Alias; | ||||||
import org.elasticsearch.cluster.metadata.IndexMetaData; | ||||||
import org.elasticsearch.common.Strings; | ||||||
import org.elasticsearch.index.Index; | ||||||
|
||||||
import java.util.List; | ||||||
|
||||||
/** | ||||||
* After we performed the index rollover we wait for the the configured number of shards for the rolled over index (ie. newly created | ||||||
* index) to become available. | ||||||
*/ | ||||||
public class WaitForActiveShardsStep extends ClusterStateWaitStep { | ||||||
|
||||||
public static final String NAME = "wait-for-active-shards"; | ||||||
|
||||||
WaitForActiveShardsStep(StepKey key, StepKey nextStepKey) { | ||||||
super(key, nextStepKey); | ||||||
} | ||||||
|
||||||
@Override | ||||||
public boolean isRetryable() { | ||||||
return true; | ||||||
} | ||||||
|
||||||
@Override | ||||||
public Result isConditionMet(Index index, ClusterState clusterState) { | ||||||
IndexMetaData originalIndexMeta = clusterState.metaData().index(index); | ||||||
dakrone marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
String rolloverAlias = RolloverAction.LIFECYCLE_ROLLOVER_ALIAS_SETTING.get(originalIndexMeta.getSettings()); | ||||||
if (Strings.isNullOrEmpty(rolloverAlias)) { | ||||||
throw new IllegalStateException("setting [" + RolloverAction.LIFECYCLE_ROLLOVER_ALIAS | ||||||
+ "] is not set on index [" + originalIndexMeta.getIndex().getName() + "]"); | ||||||
} | ||||||
|
||||||
AliasOrIndex aliasOrIndex = clusterState.metaData().getAliasAndIndexLookup().get(rolloverAlias); | ||||||
assert aliasOrIndex.isAlias() : rolloverAlias + " must be an alias but it is an index"; | ||||||
|
||||||
Alias alias = (Alias) aliasOrIndex; | ||||||
IndexMetaData aliasWriteIndex = alias.getWriteIndex(); | ||||||
String rolledIndexName; | ||||||
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.
Suggested change
|
||||||
String waitForActiveShardsSettingValue; | ||||||
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.
Suggested change
|
||||||
if (aliasWriteIndex != null) { | ||||||
rolledIndexName = aliasWriteIndex.getIndex().getName(); | ||||||
waitForActiveShardsSettingValue = aliasWriteIndex.getSettings().get("index.write.wait_for_active_shards"); | ||||||
} else { | ||||||
// if the rollover was not performed on a write index alias, the alias will be moved to the new index and it will be the only | ||||||
// index this alias points to | ||||||
List<IndexMetaData> indices = alias.getIndices(); | ||||||
assert indices.size() == 1 : "when performing rollover on alias with is_write_index = false the alias must point to only " + | ||||||
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 assertion doesn't stand in a CCR environment 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. coming up with the fix by parsing the number from the index name and finding the rolled index by "max number" |
||||||
"one index"; | ||||||
IndexMetaData indexMetaData = indices.get(0); | ||||||
rolledIndexName = indexMetaData.getIndex().getName(); | ||||||
waitForActiveShardsSettingValue = indexMetaData.getSettings().get("index.write.wait_for_active_shards"); | ||||||
} | ||||||
|
||||||
ActiveShardCount activeShardCount = ActiveShardCount.parseString(waitForActiveShardsSettingValue); | ||||||
return new Result(activeShardCount.enoughShardsActive(clusterState, rolledIndexName), null); | ||||||
dakrone marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
package org.elasticsearch.xpack.core.ilm; | ||
|
||
import org.elasticsearch.Version; | ||
import org.elasticsearch.cluster.ClusterName; | ||
import org.elasticsearch.cluster.ClusterState; | ||
import org.elasticsearch.cluster.metadata.AliasMetaData; | ||
import org.elasticsearch.cluster.metadata.IndexMetaData; | ||
import org.elasticsearch.cluster.metadata.MetaData; | ||
import org.elasticsearch.cluster.routing.IndexRoutingTable; | ||
import org.elasticsearch.cluster.routing.RoutingTable; | ||
import org.elasticsearch.cluster.routing.ShardRoutingState; | ||
import org.elasticsearch.cluster.routing.TestShardRouting; | ||
import org.elasticsearch.xpack.core.ilm.Step.StepKey; | ||
|
||
import static org.hamcrest.Matchers.is; | ||
|
||
public class WaitForActiveShardsTests extends AbstractStepTestCase<WaitForActiveShardsStep> { | ||
|
||
@Override | ||
public WaitForActiveShardsStep createRandomInstance() { | ||
StepKey stepKey = randomStepKey(); | ||
StepKey nextStepKey = randomStepKey(); | ||
|
||
return new WaitForActiveShardsStep(stepKey, nextStepKey); | ||
} | ||
|
||
@Override | ||
public WaitForActiveShardsStep mutateInstance(WaitForActiveShardsStep instance) { | ||
StepKey key = instance.getKey(); | ||
StepKey nextKey = instance.getNextStepKey(); | ||
|
||
switch (between(0, 1)) { | ||
case 0: | ||
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5)); | ||
break; | ||
case 1: | ||
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5)); | ||
break; | ||
default: | ||
throw new AssertionError("Illegal randomisation branch"); | ||
} | ||
|
||
return new WaitForActiveShardsStep(key, nextKey); | ||
} | ||
|
||
@Override | ||
public WaitForActiveShardsStep copyInstance(WaitForActiveShardsStep instance) { | ||
return new WaitForActiveShardsStep(instance.getKey(), instance.getNextStepKey()); | ||
} | ||
|
||
public void testIsConditionMetThrowsExceptionWhenRolloverAliasIsNotSet() { | ||
String alias = randomAlphaOfLength(5); | ||
IndexMetaData indexMetaData = IndexMetaData.builder(randomAlphaOfLength(10)) | ||
.putAlias(AliasMetaData.builder(alias)) | ||
.settings(settings(Version.CURRENT)) | ||
.numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build(); | ||
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT) | ||
.metaData(MetaData.builder().put(indexMetaData, true).build()) | ||
.build(); | ||
|
||
try { | ||
createRandomInstance().isConditionMet(indexMetaData.getIndex(), clusterState); | ||
fail("expected the invocation to fail"); | ||
} catch (IllegalStateException e) { | ||
assertThat(e.getMessage(), is("setting [" + RolloverAction.LIFECYCLE_ROLLOVER_ALIAS | ||
+ "] is not set on index [" + indexMetaData.getIndex().getName() + "]")); | ||
} | ||
} | ||
|
||
public void testResultEvaluatedOnWriteIndexAliasWhenExists() { | ||
String alias = randomAlphaOfLength(5); | ||
IndexMetaData originalIndex = IndexMetaData.builder("index-000000") | ||
.putAlias(AliasMetaData.builder(alias).writeIndex(false)) | ||
.settings(settings(Version.CURRENT).put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias)) | ||
.numberOfShards(1) | ||
.numberOfReplicas(randomIntBetween(0, 5)) | ||
.build(); | ||
IndexMetaData rolledIndex = IndexMetaData.builder("index-000001") | ||
.putAlias(AliasMetaData.builder(alias).writeIndex(true)) | ||
.settings(settings(Version.CURRENT) | ||
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias) | ||
.put("index.write.wait_for_active_shards", "all") | ||
) | ||
.numberOfShards(1) | ||
.numberOfReplicas(1) | ||
.build(); | ||
IndexRoutingTable.Builder routingTable = new IndexRoutingTable.Builder(rolledIndex.getIndex()); | ||
routingTable.addShard(TestShardRouting.newShardRouting(rolledIndex.getIndex().getName(), 0, "node", null, true, | ||
ShardRoutingState.STARTED)); | ||
routingTable.addShard(TestShardRouting.newShardRouting(rolledIndex.getIndex().getName(), 0, "node2", null, false, | ||
ShardRoutingState.STARTED)); | ||
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT) | ||
.metaData(MetaData.builder().put(originalIndex, true) | ||
.put(rolledIndex, true) | ||
.build()) | ||
.routingTable(RoutingTable.builder().add(routingTable.build()).build()) | ||
.build(); | ||
|
||
assertThat("the rolled index has both the primary and the replica shards started so the condition should be met", | ||
createRandomInstance().isConditionMet(originalIndex.getIndex(), clusterState).isComplete(), is(true)); | ||
} | ||
|
||
public void testResultEvaluatedOnOnlyIndexTheAliasPointsToIfWriteIndexIsNull() { | ||
String alias = randomAlphaOfLength(5); | ||
IndexMetaData originalIndex = IndexMetaData.builder("index-000000") | ||
.settings(settings(Version.CURRENT).put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias)) | ||
.numberOfShards(1) | ||
.numberOfReplicas(randomIntBetween(0, 5)) | ||
.build(); | ||
IndexMetaData rolledIndex = IndexMetaData.builder("index-000001") | ||
.putAlias(AliasMetaData.builder(alias).writeIndex(false)) | ||
.settings(settings(Version.CURRENT) | ||
.put(RolloverAction.LIFECYCLE_ROLLOVER_ALIAS, alias) | ||
.put("index.write.wait_for_active_shards", "all") | ||
) | ||
.numberOfShards(1) | ||
.numberOfReplicas(1) | ||
.build(); | ||
IndexRoutingTable.Builder routingTable = new IndexRoutingTable.Builder(rolledIndex.getIndex()); | ||
routingTable.addShard(TestShardRouting.newShardRouting(rolledIndex.getIndex().getName(), 0, "node", null, true, | ||
ShardRoutingState.STARTED)); | ||
routingTable.addShard(TestShardRouting.newShardRouting(rolledIndex.getIndex().getName(), 0, "node2", null, false, | ||
ShardRoutingState.STARTED)); | ||
ClusterState clusterState = ClusterState.builder(ClusterName.DEFAULT) | ||
.metaData(MetaData.builder().put(originalIndex, true) | ||
.put(rolledIndex, true) | ||
.build()) | ||
.routingTable(RoutingTable.builder().add(routingTable.build()).build()) | ||
.build(); | ||
|
||
assertThat("the index the alias is pointing to has both the primary and the replica shards started so the condition should be" + | ||
" met", createRandomInstance().isConditionMet(originalIndex.getIndex(), clusterState).isComplete(), is(true)); | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.