Selaa lähdekoodia

[ILM] Fix the migrate to tiers service and migrate action tiers configuration (#95934)

The migrate action (although no allowed in the frozen phase) would seem
to convert `frozen` to `data_frozen,data_cold,data_warm,data_hot` tier
configuration. As the migrate action is not allowed in the frozen phase
this would never happen, however the code is confusing as it seems like
it could.

The migrate to data tiers routing service shared the code used by the
`migrate` action that converted `frozen` to
`data_frozen,data_cold,data_warm,data_hot` if it would encounter an
index without any `_tier_preference` setting  but with a custom node
attribute configured to `frozen` e.g. `include.data: frozen`

As part of https://github.com/elastic/elasticsearch/issues/84758 we have
seen frozen indices with the `data_frozen,data_cold,data_warm,data_hot`
tier preference however we could never reproduce it.

Relates to https://github.com/elastic/elasticsearch/issues/84758
Andrei Dan 2 vuotta sitten
vanhempi
commit
f8b367d2bc

+ 5 - 0
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: []

+ 2 - 4
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
 <<tier-preference-allocation-filter, `index.routing.allocation.include._tier_preference`>>
-of `data_frozen,data_cold,data_warm,data_hot`. This moves the index to nodes in the
-<<frozen-tier, frozen tier>>. If there are no nodes in the frozen tier, it falls back to the
-<<cold-tier, cold>> tier, then the <<warm-tier, warm>> tier, then finally the <<hot-tier, hot>>
-tier.
+of `data_frozen`. This moves the index to nodes in the
+<<frozen-tier, frozen tier>>.
 
 The migrate action is not allowed in the hot phase.
 The initial index allocation is performed <<data-tier-allocation, automatically>>,

+ 9 - 4
server/src/main/java/org/elasticsearch/cluster/routing/allocation/DataTier.java

@@ -100,10 +100,15 @@ public class DataTier {
         final Map<String, Settings> 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);

+ 2 - 0
server/src/test/java/org/elasticsearch/cluster/routing/allocation/DataTierTests.java

@@ -28,6 +28,7 @@ import java.util.Set;
 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 class DataTierTests extends ESTestCase {
         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]"));
     }

+ 22 - 2
x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/cluster/metadata/MetadataMigrateToDataTiersRoutingServiceTests.java

@@ -148,7 +148,7 @@ public class MetadataMigrateToDataTiersRoutingServiceTests extends ESTestCase {
         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 class MetadataMigrateToDataTiersRoutingServiceTests extends ESTestCase {
     }
 
     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 class MetadataMigrateToDataTiersRoutingServiceTests extends ESTestCase {
             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<String> 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