Skip to content
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

Adding translog durability validation in index templates #15494

Merged
merged 4 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Adding translog durability validation in index templates
Signed-off-by: Shourya Dutta Biswas <114977491+shourya035@users.noreply.github.com>
  • Loading branch information
shourya035 committed Aug 30, 2024
commit 96318cc02f61ee1a1eba11ae2812fcc1115792e0
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -932,4 +933,38 @@ public void testFlushOnTooManyRemoteTranslogFiles() throws Exception {
assertEquals(totalFiles, 501L);
}
}

public void testAsyncTranslogDurabilityRestrictionsThroughIdxTemplates() throws Exception {
logger.info("Starting up cluster manager with cluster.remote_store.index.restrict.async-durability set to true");
String cm1 = internalCluster().startClusterManagerOnlyNode(
Settings.builder().put(IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING.getKey(), true).build()
);
internalCluster().startDataOnlyNode();
ensureStableCluster(2);
assertThrows(
IllegalArgumentException.class,
() -> internalCluster().client()
.admin()
.indices()
.preparePutTemplate("test")
.setPatterns(Arrays.asList("test*"))
.setSettings(Settings.builder().put(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.getKey(), "async"))
.get()
);
logger.info("Starting up another cluster manager with cluster.remote_store.index.restrict.async-durability set to false");
internalCluster().startClusterManagerOnlyNode(
Settings.builder().put(IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING.getKey(), false).build()
);
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(cm1));
ensureStableCluster(2);
assertAcked(
internalCluster().client()
.admin()
.indices()
.preparePutTemplate("test")
.setPatterns(Arrays.asList("test*"))
.setSettings(Settings.builder().put(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.getKey(), "async"))
.get()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,11 @@
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.index.IndexService;
import org.opensearch.index.IndexSettings;
import org.opensearch.index.mapper.MapperParsingException;
import org.opensearch.index.mapper.MapperService;
import org.opensearch.index.mapper.MapperService.MergeReason;
import org.opensearch.index.translog.Translog;
import org.opensearch.indices.IndexTemplateMissingException;
import org.opensearch.indices.IndicesService;
import org.opensearch.indices.InvalidIndexTemplateException;
Expand Down Expand Up @@ -1632,8 +1634,9 @@ private void validate(String name, @Nullable Settings settings, List<String> ind
);
validationErrors.addAll(indexSettingsValidation);

// validate index refresh interval settings
// validate index refresh interval and translog durability settings
validateRefreshIntervalSettings(settings, clusterService.getClusterSettings());
validateTranslogDurabilitySettingsInTemplate(settings, clusterService.getClusterSettings());
}

if (indexPatterns.stream().anyMatch(Regex::isMatchAllPattern)) {
Expand All @@ -1659,6 +1662,29 @@ private void validate(String name, @Nullable Settings settings, List<String> ind
}
}

/**
* Validates {@code index.translog.durability} is not async with the incoming index template
* if the {@code cluster.remote_store.index.restrict.async-durability} is set to true.
*
* @param requestSettings settings passed during template creation
* @param clusterSettings current cluster settings
*/
private void validateTranslogDurabilitySettingsInTemplate(Settings requestSettings, ClusterSettings clusterSettings) {
linuxpi marked this conversation as resolved.
Show resolved Hide resolved
if (IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.exists(requestSettings) == false
|| clusterSettings.get(IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING) == false) {
return;
}
Translog.Durability durability = IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.get(requestSettings);
if (durability.equals(Translog.Durability.ASYNC)) {
throw new IllegalArgumentException(
"index setting [index.translog.durability=async] is not allowed as cluster setting ["
linuxpi marked this conversation as resolved.
Show resolved Hide resolved
+ IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING.getKey()
+ "=true]"
);
}

}

/**
* Listener for putting metadata in the template
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.env.Environment;
import org.opensearch.index.IndexSettings;
import org.opensearch.index.codec.CodecService;
import org.opensearch.index.engine.EngineConfig;
import org.opensearch.index.mapper.MapperParsingException;
Expand Down Expand Up @@ -2410,9 +2411,27 @@ public void testLegacyNoopUpdate() {
assertThat(MetadataIndexTemplateService.innerPutTemplate(state, pr, new IndexTemplateMetadata.Builder("id")), equalTo(state));
}

public void testAsyncTranslogDurabilityBlocked() {
Settings clusterSettings = Settings.builder()
.put(IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING.getKey(), true)
.build();
PutRequest request = new PutRequest("test", "test_replicas");
request.patterns(singletonList("test_shards_wait*"));
Settings.Builder settingsBuilder = builder().put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, "1")
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, "1")
.put(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.getKey(), "async");
request.settings(settingsBuilder.build());
List<Throwable> throwables = putTemplate(xContentRegistry(), request, clusterSettings);
assertThat(throwables.get(0), instanceOf(IllegalArgumentException.class));
}

private static List<Throwable> putTemplate(NamedXContentRegistry xContentRegistry, PutRequest request) {
return putTemplate(xContentRegistry, request, Settings.EMPTY);
}

private static List<Throwable> putTemplate(NamedXContentRegistry xContentRegistry, PutRequest request, Settings incomingSettings) {
shourya035 marked this conversation as resolved.
Show resolved Hide resolved
ClusterService clusterService = mock(ClusterService.class);
Settings settings = Settings.builder().put(PATH_HOME_SETTING.getKey(), "dummy").build();
Settings settings = Settings.builder().put(incomingSettings).put(PATH_HOME_SETTING.getKey(), "dummy").build();
ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
Metadata metadata = Metadata.builder().build();
ClusterState clusterState = ClusterState.builder(org.opensearch.cluster.ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY))
Expand Down