|
@@ -22,6 +22,7 @@ import org.elasticsearch.action.admin.indices.rollover.RolloverConditions;
|
|
|
import org.elasticsearch.action.admin.indices.rollover.RolloverConfiguration;
|
|
|
import org.elasticsearch.action.admin.indices.rollover.RolloverInfo;
|
|
|
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
|
|
|
+import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
|
|
|
import org.elasticsearch.action.support.DefaultShardOperationFailedException;
|
|
|
import org.elasticsearch.client.internal.Client;
|
|
|
import org.elasticsearch.cluster.ClusterName;
|
|
@@ -43,6 +44,7 @@ import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.unit.ByteSizeValue;
|
|
|
import org.elasticsearch.core.TimeValue;
|
|
|
import org.elasticsearch.index.Index;
|
|
|
+import org.elasticsearch.index.MergePolicyConfig;
|
|
|
import org.elasticsearch.test.ESTestCase;
|
|
|
import org.elasticsearch.test.EqualsHashCodeTestUtils;
|
|
|
import org.elasticsearch.test.client.NoOpClient;
|
|
@@ -69,8 +71,12 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
import static org.elasticsearch.dlm.DLMFixtures.createDataStream;
|
|
|
+import static org.elasticsearch.dlm.DataLifecycleService.DATA_STREAM_MERGE_POLICY_TARGET_FACTOR_SETTING;
|
|
|
+import static org.elasticsearch.dlm.DataLifecycleService.DATA_STREAM_MERGE_POLICY_TARGET_FLOOR_SEGMENT_SETTING;
|
|
|
import static org.elasticsearch.dlm.DataLifecycleService.FORCE_MERGE_COMPLETED_TIMESTAMP_METADATA_KEY;
|
|
|
import static org.elasticsearch.dlm.DataLifecycleService.LIFECYCLE_CUSTOM_INDEX_METADATA_KEY;
|
|
|
+import static org.elasticsearch.dlm.DataLifecycleService.ONE_HUNDRED_MB;
|
|
|
+import static org.elasticsearch.dlm.DataLifecycleService.TARGET_MERGE_FACTOR_VALUE;
|
|
|
import static org.elasticsearch.test.ClusterServiceUtils.createClusterService;
|
|
|
import static org.elasticsearch.test.ClusterServiceUtils.setState;
|
|
|
import static org.hamcrest.Matchers.equalTo;
|
|
@@ -95,6 +101,8 @@ public class DataLifecycleServiceTests extends ESTestCase {
|
|
|
threadPool = new TestThreadPool(getTestName());
|
|
|
Set<Setting<?>> builtInClusterSettings = new HashSet<>(ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
|
|
|
builtInClusterSettings.add(DataLifecycleService.DATA_STREAM_LIFECYCLE_POLL_INTERVAL_SETTING);
|
|
|
+ builtInClusterSettings.add(DATA_STREAM_MERGE_POLICY_TARGET_FLOOR_SEGMENT_SETTING);
|
|
|
+ builtInClusterSettings.add(DATA_STREAM_MERGE_POLICY_TARGET_FACTOR_SETTING);
|
|
|
ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, builtInClusterSettings);
|
|
|
clusterService = createClusterService(threadPool, clusterSettings);
|
|
|
|
|
@@ -338,7 +346,8 @@ public class DataLifecycleServiceTests extends ESTestCase {
|
|
|
builder,
|
|
|
dataStreamName,
|
|
|
numBackingIndices,
|
|
|
- settings(Version.CURRENT),
|
|
|
+ settings(Version.CURRENT).put(MergePolicyConfig.INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING.getKey(), ONE_HUNDRED_MB)
|
|
|
+ .put(MergePolicyConfig.INDEX_MERGE_POLICY_MERGE_FACTOR_SETTING.getKey(), TARGET_MERGE_FACTOR_VALUE),
|
|
|
new DataLifecycle(TimeValue.MAX_VALUE),
|
|
|
now
|
|
|
);
|
|
@@ -396,7 +405,14 @@ public class DataLifecycleServiceTests extends ESTestCase {
|
|
|
// Add another index backing, and make sure that the only thing that happens is another force merge
|
|
|
IndexMetadata.Builder indexMetaBuilder = IndexMetadata.builder(
|
|
|
DataStream.getDefaultBackingIndexName(dataStreamName, numBackingIndices + 1)
|
|
|
- ).settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1).creationDate(now - 3000L);
|
|
|
+ )
|
|
|
+ .settings(
|
|
|
+ settings(Version.CURRENT).put(MergePolicyConfig.INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING.getKey(), ONE_HUNDRED_MB)
|
|
|
+ .put(MergePolicyConfig.INDEX_MERGE_POLICY_MERGE_FACTOR_SETTING.getKey(), TARGET_MERGE_FACTOR_VALUE)
|
|
|
+ )
|
|
|
+ .numberOfShards(1)
|
|
|
+ .numberOfReplicas(1)
|
|
|
+ .creationDate(now - 3000L);
|
|
|
MaxAgeCondition rolloverCondition = new MaxAgeCondition(TimeValue.timeValueMillis(now - 2000L));
|
|
|
indexMetaBuilder.putRolloverInfo(new RolloverInfo(dataStreamName, List.of(rolloverCondition), now - 2000L));
|
|
|
IndexMetadata newIndexMetadata = indexMetaBuilder.build();
|
|
@@ -441,7 +457,8 @@ public class DataLifecycleServiceTests extends ESTestCase {
|
|
|
builder,
|
|
|
dataStreamName,
|
|
|
numBackingIndices,
|
|
|
- settings(Version.CURRENT),
|
|
|
+ settings(Version.CURRENT).put(MergePolicyConfig.INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING.getKey(), ONE_HUNDRED_MB)
|
|
|
+ .put(MergePolicyConfig.INDEX_MERGE_POLICY_MERGE_FACTOR_SETTING.getKey(), TARGET_MERGE_FACTOR_VALUE),
|
|
|
new DataLifecycle(TimeValue.MAX_VALUE),
|
|
|
now
|
|
|
);
|
|
@@ -620,7 +637,14 @@ public class DataLifecycleServiceTests extends ESTestCase {
|
|
|
builder.put(dataStream);
|
|
|
IndexMetadata.Builder indexMetaBuilder = IndexMetadata.builder(
|
|
|
DataStream.getDefaultBackingIndexName(dataStreamName, numBackingIndices + 1)
|
|
|
- ).settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1).creationDate(now - 3000L);
|
|
|
+ )
|
|
|
+ .settings(
|
|
|
+ settings(Version.CURRENT).put(MergePolicyConfig.INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING.getKey(), ONE_HUNDRED_MB)
|
|
|
+ .put(MergePolicyConfig.INDEX_MERGE_POLICY_MERGE_FACTOR_SETTING.getKey(), TARGET_MERGE_FACTOR_VALUE)
|
|
|
+ )
|
|
|
+ .numberOfShards(1)
|
|
|
+ .numberOfReplicas(1)
|
|
|
+ .creationDate(now - 3000L);
|
|
|
MaxAgeCondition rolloverCondition = new MaxAgeCondition(TimeValue.timeValueMillis(now - 2000L));
|
|
|
indexMetaBuilder.putRolloverInfo(new RolloverInfo(dataStreamName, List.of(rolloverCondition), now - 2000L));
|
|
|
IndexMetadata newIndexMetadata = indexMetaBuilder.build();
|
|
@@ -710,30 +734,6 @@ public class DataLifecycleServiceTests extends ESTestCase {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * Creates a test cluster state with the given indexName. If customDlmMetadata is not null, it is added as the value of the index's
|
|
|
- * custom metadata named "dlm".
|
|
|
- */
|
|
|
- private ClusterState createClusterState(String indexName, Map<String, String> customDlmMetadata) {
|
|
|
- var routingTableBuilder = RoutingTable.builder();
|
|
|
- Metadata.Builder metadataBuilder = Metadata.builder();
|
|
|
- Map<String, IndexMetadata> indices = new HashMap<>();
|
|
|
- Settings indexSettings = Settings.builder()
|
|
|
- .put(IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), randomIntBetween(1, 10))
|
|
|
- .put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), randomIntBetween(0, 3))
|
|
|
- .put(IndexMetadata.SETTING_INDEX_VERSION_CREATED.getKey(), Version.CURRENT)
|
|
|
- .build();
|
|
|
- IndexMetadata.Builder indexMetadataBuilder = IndexMetadata.builder(indexName).version(randomLong()).settings(indexSettings);
|
|
|
- if (customDlmMetadata != null) {
|
|
|
- indexMetadataBuilder.putCustom(LIFECYCLE_CUSTOM_INDEX_METADATA_KEY, customDlmMetadata);
|
|
|
- }
|
|
|
- indices.put(indexName, indexMetadataBuilder.build());
|
|
|
- return ClusterState.builder(new ClusterName("test-cluster"))
|
|
|
- .routingTable(routingTableBuilder.build())
|
|
|
- .metadata(metadataBuilder.indices(indices).build())
|
|
|
- .build();
|
|
|
- }
|
|
|
-
|
|
|
public void testDefaultRolloverRequest() {
|
|
|
// test auto max_age and another concrete condition
|
|
|
{
|
|
@@ -804,6 +804,106 @@ public class DataLifecycleServiceTests extends ESTestCase {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ public void testMergePolicySettingsAreConfiguredBeforeForcemerge() throws Exception {
|
|
|
+ String dataStreamName = randomAlphaOfLength(10).toLowerCase(Locale.ROOT);
|
|
|
+ int numBackingIndices = 3;
|
|
|
+ Metadata.Builder builder = Metadata.builder();
|
|
|
+ DataStream dataStream = createDataStream(
|
|
|
+ builder,
|
|
|
+ dataStreamName,
|
|
|
+ numBackingIndices,
|
|
|
+ settings(Version.CURRENT),
|
|
|
+ new DataLifecycle(TimeValue.MAX_VALUE),
|
|
|
+ now
|
|
|
+ );
|
|
|
+ builder.put(dataStream);
|
|
|
+
|
|
|
+ String nodeId = "localNode";
|
|
|
+ DiscoveryNodes.Builder nodesBuilder = buildNodes(nodeId);
|
|
|
+ // we are the master node
|
|
|
+ nodesBuilder.masterNodeId(nodeId);
|
|
|
+ ClusterState state = ClusterState.builder(ClusterName.DEFAULT).metadata(builder).nodes(nodesBuilder).build();
|
|
|
+ setState(clusterService, state);
|
|
|
+ dataLifecycleService.run(clusterService.state());
|
|
|
+
|
|
|
+ // There are 3 backing indices. One gets rolled over. The other two will need to have their merge policy updated:
|
|
|
+ assertBusy(() -> assertThat(clientSeenRequests.size(), is(3)), 30, TimeUnit.SECONDS);
|
|
|
+ assertThat(clientSeenRequests.get(0), instanceOf(RolloverRequest.class));
|
|
|
+ assertThat(((RolloverRequest) clientSeenRequests.get(0)).getRolloverTarget(), is(dataStreamName));
|
|
|
+ List<UpdateSettingsRequest> updateSettingsRequests = clientSeenRequests.subList(1, 3)
|
|
|
+ .stream()
|
|
|
+ .map(transportRequest -> (UpdateSettingsRequest) transportRequest)
|
|
|
+ .toList();
|
|
|
+ assertThat(updateSettingsRequests.get(0).indices()[0], is(dataStream.getIndices().get(0).getName()));
|
|
|
+ assertThat(updateSettingsRequests.get(1).indices()[0], is(dataStream.getIndices().get(1).getName()));
|
|
|
+
|
|
|
+ for (UpdateSettingsRequest settingsRequest : updateSettingsRequests) {
|
|
|
+ assertThat(
|
|
|
+ settingsRequest.settings()
|
|
|
+ .getAsBytesSize(MergePolicyConfig.INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING.getKey(), ByteSizeValue.MINUS_ONE),
|
|
|
+ is(ONE_HUNDRED_MB)
|
|
|
+ );
|
|
|
+ assertThat(
|
|
|
+ settingsRequest.settings().getAsInt(MergePolicyConfig.INDEX_MERGE_POLICY_MERGE_FACTOR_SETTING.getKey(), -1),
|
|
|
+ is(TARGET_MERGE_FACTOR_VALUE)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ // No changes, so running should not create any more requests
|
|
|
+ dataLifecycleService.run(clusterService.state());
|
|
|
+ assertThat(clientSeenRequests.size(), is(3));
|
|
|
+
|
|
|
+ // let's add one more backing index that has the expected merge policy and check the data stream lifecycle issues a forcemerge
|
|
|
+ // request for it
|
|
|
+ IndexMetadata.Builder indexMetaBuilder = IndexMetadata.builder(
|
|
|
+ DataStream.getDefaultBackingIndexName(dataStreamName, numBackingIndices + 1)
|
|
|
+ )
|
|
|
+ .settings(
|
|
|
+ settings(Version.CURRENT).put(MergePolicyConfig.INDEX_MERGE_POLICY_FLOOR_SEGMENT_SETTING.getKey(), ONE_HUNDRED_MB)
|
|
|
+ .put(MergePolicyConfig.INDEX_MERGE_POLICY_MERGE_FACTOR_SETTING.getKey(), TARGET_MERGE_FACTOR_VALUE)
|
|
|
+ )
|
|
|
+ .numberOfShards(1)
|
|
|
+ .numberOfReplicas(1)
|
|
|
+ .creationDate(now - 3000L);
|
|
|
+ MaxAgeCondition rolloverCondition = new MaxAgeCondition(TimeValue.timeValueMillis(now - 2000L));
|
|
|
+ indexMetaBuilder.putRolloverInfo(new RolloverInfo(dataStreamName, List.of(rolloverCondition), now - 2000L));
|
|
|
+ IndexMetadata newIndexMetadata = indexMetaBuilder.build();
|
|
|
+ builder = Metadata.builder(clusterService.state().metadata()).put(newIndexMetadata, true);
|
|
|
+ state = ClusterState.builder(clusterService.state()).metadata(builder).build();
|
|
|
+ setState(clusterService, state);
|
|
|
+ DataStream modifiedDataStream = dataStream.addBackingIndex(clusterService.state().metadata(), newIndexMetadata.getIndex());
|
|
|
+ builder = Metadata.builder(clusterService.state().metadata());
|
|
|
+ builder.put(modifiedDataStream);
|
|
|
+ state = ClusterState.builder(clusterService.state()).metadata(builder).build();
|
|
|
+ setState(clusterService, state);
|
|
|
+ dataLifecycleService.run(clusterService.state());
|
|
|
+ assertBusy(() -> assertThat(clientSeenRequests.size(), is(4)));
|
|
|
+ assertThat(((ForceMergeRequest) clientSeenRequests.get(3)).indices().length, is(1));
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Creates a test cluster state with the given indexName. If customDlmMetadata is not null, it is added as the value of the index's
|
|
|
+ * custom metadata named "dlm".
|
|
|
+ */
|
|
|
+ private ClusterState createClusterState(String indexName, Map<String, String> customDlmMetadata) {
|
|
|
+ var routingTableBuilder = RoutingTable.builder();
|
|
|
+ Metadata.Builder metadataBuilder = Metadata.builder();
|
|
|
+ Map<String, IndexMetadata> indices = new HashMap<>();
|
|
|
+ Settings indexSettings = Settings.builder()
|
|
|
+ .put(IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), randomIntBetween(1, 10))
|
|
|
+ .put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), randomIntBetween(0, 3))
|
|
|
+ .put(IndexMetadata.SETTING_INDEX_VERSION_CREATED.getKey(), Version.CURRENT)
|
|
|
+ .build();
|
|
|
+ IndexMetadata.Builder indexMetadataBuilder = IndexMetadata.builder(indexName).version(randomLong()).settings(indexSettings);
|
|
|
+ if (customDlmMetadata != null) {
|
|
|
+ indexMetadataBuilder.putCustom(LIFECYCLE_CUSTOM_INDEX_METADATA_KEY, customDlmMetadata);
|
|
|
+ }
|
|
|
+ indices.put(indexName, indexMetadataBuilder.build());
|
|
|
+ return ClusterState.builder(new ClusterName("test-cluster"))
|
|
|
+ .routingTable(routingTableBuilder.build())
|
|
|
+ .metadata(metadataBuilder.indices(indices).build())
|
|
|
+ .build();
|
|
|
+ }
|
|
|
+
|
|
|
private static DataLifecycleService.ForceMergeRequestWrapper copyForceMergeRequestWrapperRequest(
|
|
|
DataLifecycleService.ForceMergeRequestWrapper original
|
|
|
) {
|