diff --git a/docs/changelog/95934.yaml b/docs/changelog/95934.yaml new file mode 100644 index 0000000000000..ee4d72f4c8b25 --- /dev/null +++ b/docs/changelog/95934.yaml @@ -0,0 +1,5 @@ +pr: 95934 +summary: "[ILM] Fix the migrate to tiers service and migrate action tiers configuration" +area: ILM+SLM +type: bug +issues: [] diff --git a/docs/reference/ilm/actions/ilm-migrate.asciidoc b/docs/reference/ilm/actions/ilm-migrate.asciidoc index 61ce2e1a4064d..d3e55a35c5c9a 100644 --- a/docs/reference/ilm/actions/ilm-migrate.asciidoc +++ b/docs/reference/ilm/actions/ilm-migrate.asciidoc @@ -31,10 +31,8 @@ to `data_cold,data_warm,data_hot`. This moves the index to nodes in the The migrate action is not allowed in the frozen phase. The frozen phase directly mounts the searchable snapshot using a <> -of `data_frozen,data_cold,data_warm,data_hot`. This moves the index to nodes in the -<>. If there are no nodes in the frozen tier, it falls back to the -<> tier, then the <> tier, then finally the <> -tier. +of `data_frozen`. This moves the index to nodes in the +<>. The migrate action is not allowed in the hot phase. The initial index allocation is performed <>, diff --git a/server/src/main/java/org/elasticsearch/cluster/routing/allocation/DataTier.java b/server/src/main/java/org/elasticsearch/cluster/routing/allocation/DataTier.java index 69b8f5b29d937..d2b2c22a287fa 100644 --- a/server/src/main/java/org/elasticsearch/cluster/routing/allocation/DataTier.java +++ b/server/src/main/java/org/elasticsearch/cluster/routing/allocation/DataTier.java @@ -100,10 +100,15 @@ public class DataTier { final Map tmpSettings = new HashMap<>(); for (int i = 0, ordered_frozen_to_hot_tiersSize = ORDERED_FROZEN_TO_HOT_TIERS.size(); i < ordered_frozen_to_hot_tiersSize; i++) { String tier = ORDERED_FROZEN_TO_HOT_TIERS.get(i); - final String prefTierString = String.join(",", ORDERED_FROZEN_TO_HOT_TIERS.subList(i, ORDERED_FROZEN_TO_HOT_TIERS.size())) - .intern(); - tmp.put(tier, prefTierString); - tmpSettings.put(tier, Settings.builder().put(DataTier.TIER_PREFERENCE, prefTierString).build()); + if (tier.equals(DATA_FROZEN)) { + tmp.put(tier, DATA_FROZEN); + tmpSettings.put(DATA_FROZEN, Settings.builder().put(DataTier.TIER_PREFERENCE, DATA_FROZEN).build()); + } else { + final String prefTierString = String.join(",", ORDERED_FROZEN_TO_HOT_TIERS.subList(i, ORDERED_FROZEN_TO_HOT_TIERS.size())) + .intern(); + tmp.put(tier, prefTierString); + tmpSettings.put(tier, Settings.builder().put(DataTier.TIER_PREFERENCE, prefTierString).build()); + } } PREFERENCE_TIER_CONFIGURATIONS = Map.copyOf(tmp); PREFERENCE_TIER_CONFIGURATION_SETTINGS = Map.copyOf(tmpSettings); diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/DataTierTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/DataTierTests.java index 2fdac9bbef279..5d3fab2c3c050 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/allocation/DataTierTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/allocation/DataTierTests.java @@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger; import static org.elasticsearch.cluster.routing.allocation.DataTier.DATA_COLD; +import static org.elasticsearch.cluster.routing.allocation.DataTier.DATA_FROZEN; import static org.elasticsearch.cluster.routing.allocation.DataTier.DATA_HOT; import static org.elasticsearch.cluster.routing.allocation.DataTier.DATA_WARM; import static org.elasticsearch.cluster.routing.allocation.DataTier.getPreferredTiersConfiguration; @@ -120,6 +121,7 @@ public void testGetPreferredTiersConfiguration() { assertThat(getPreferredTiersConfiguration(DATA_HOT), is(DATA_HOT)); assertThat(getPreferredTiersConfiguration(DATA_WARM), is(DATA_WARM + "," + DATA_HOT)); assertThat(getPreferredTiersConfiguration(DATA_COLD), is(DATA_COLD + "," + DATA_WARM + "," + DATA_HOT)); + assertThat(getPreferredTiersConfiguration(DATA_FROZEN), is(DATA_FROZEN)); IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> getPreferredTiersConfiguration("no_tier")); assertThat(exception.getMessage(), is("invalid data tier [no_tier]")); } diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/cluster/metadata/MetadataMigrateToDataTiersRoutingServiceTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/cluster/metadata/MetadataMigrateToDataTiersRoutingServiceTests.java index 2b12c6597cc6e..df4b8b52a696c 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/cluster/metadata/MetadataMigrateToDataTiersRoutingServiceTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/cluster/metadata/MetadataMigrateToDataTiersRoutingServiceTests.java @@ -148,7 +148,7 @@ public void testMigrateIlmPolicyForIndexWithoutILMMetadata() { assertThat(migratedColdAllocateAction.getRequire().size(), is(0)); } - public void testMigrateIlmPolicyFOrPhaseWithDeactivatedMigrateAction() { + public void testMigrateIlmPolicyForPhaseWithDeactivatedMigrateAction() { ShrinkAction shrinkAction = new ShrinkAction(2, null); AllocateAction warmAllocateAction = new AllocateAction(null, null, Map.of("data", "warm"), null, Map.of("rack", "rack1")); @@ -511,7 +511,7 @@ public void testAllocateActionDefinesRoutingRules() { } public void testConvertAttributeValueToTierPreference() { - assertThat(convertAttributeValueToTierPreference("frozen"), is("data_frozen,data_cold,data_warm,data_hot")); + assertThat(convertAttributeValueToTierPreference("frozen"), is("data_frozen")); assertThat(convertAttributeValueToTierPreference("cold"), is("data_cold,data_warm,data_hot")); assertThat(convertAttributeValueToTierPreference("warm"), is("data_warm,data_hot")); assertThat(convertAttributeValueToTierPreference("hot"), is("data_hot")); @@ -560,6 +560,26 @@ public void testMigrateIndices() { assertThat(migratedIndex.getSettings().get(TIER_PREFERENCE), is("data_warm,data_hot")); } + { + // test the migration of `include.data: frozen` configuration to the equivalent _tier_preference routing + IndexMetadata.Builder indexWithFrozenDataAttribute = IndexMetadata.builder("indexWithFrozenDataAttribute") + .settings(getBaseIndexSettings().put(DATA_ROUTING_INCLUDE_SETTING, "frozen")); + ClusterState state = ClusterState.builder(ClusterName.DEFAULT) + .metadata(Metadata.builder().put(indexWithFrozenDataAttribute)) + .build(); + + Metadata.Builder mb = Metadata.builder(state.metadata()); + + List migratedIndices = migrateIndices(mb, state, "data"); + assertThat(migratedIndices.size(), is(1)); + assertThat(migratedIndices.get(0), is("indexWithFrozenDataAttribute")); + + ClusterState migratedState = ClusterState.builder(ClusterName.DEFAULT).metadata(mb).build(); + IndexMetadata migratedIndex = migratedState.metadata().index("indexWithFrozenDataAttribute"); + assertThat(migratedIndex.getSettings().get(DATA_ROUTING_INCLUDE_SETTING), nullValue()); + assertThat(migratedIndex.getSettings().get(TIER_PREFERENCE), is("data_frozen")); + } + { // since the index has a _tier_preference configuration the migrated index should still contain it and have ALL the `data` // attributes routing removed