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

Added new Setting property UnmodifiableOnRestore to prevent updating settings on restore snapshot #16957

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

anntians
Copy link

@anntians anntians commented Jan 6, 2025

Description

This PR adds a new Setting property UnmodifiableOnRestore to prevent customers from updating certain settings on restore snapshot. The motivation behind this change is to prevent customers from updating index.knn setting when restoring a snapshot. The PR is related to another PR (opensearch-project/k-NN#2348) which fixes a bug by making index.knn setting immutable after index creation. However, that PR doesn't cover the case for snapshots, so this PR adds Setting property UnmodifiableOnRestore so that index.knn will be immutable when restoring an index from a snapshot.

Related Issues

Resolves Issue 2334 in KNN repository: opensearch-project/k-NN#2334
#17019

Check List

  • Functionality includes testing.
  • API changes companion pull request created, if applicable.
  • Public documentation issue/PR created, if applicable.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

Copy link
Contributor

github-actions bot commented Jan 6, 2025

✅ Gradle check result for 4a659c0: SUCCESS

Copy link

codecov bot commented Jan 6, 2025

Codecov Report

Attention: Patch coverage is 88.23529% with 2 lines in your changes missing coverage. Please review.

Project coverage is 72.19%. Comparing base (6b1861a) to head (e517731).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
.../java/org/opensearch/snapshots/RestoreService.java 80.00% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main   #16957      +/-   ##
============================================
- Coverage     72.23%   72.19%   -0.04%     
+ Complexity    65335    65309      -26     
============================================
  Files          5301     5302       +1     
  Lines        303824   303921      +97     
  Branches      44033    44048      +15     
============================================
- Hits         219471   219427      -44     
- Misses        66363    66543     +180     
+ Partials      17990    17951      -39     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

github-actions bot commented Jan 7, 2025

❌ Gradle check result for f33c9bc: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

…utable on restore snapshot

Signed-off-by: AnnTian Shao <[email protected]>
Copy link
Contributor

❌ Gradle check result for fddd875: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: Tommy Shao <[email protected]>
Signed-off-by: AnnTian Shao <[email protected]>
Copy link
Contributor

✅ Gradle check result for 1227bbb: SUCCESS

Copy link
Contributor

✅ Gradle check result for 2afd94e: SUCCESS

@@ -740,6 +740,23 @@ public void testInvalidRestoreRequestScenarios() throws Exception {
);
assertTrue(exception.getMessage().contains("cannot modify setting [index.remote_store.segment.repository]" + " on restore"));

// try index restore with index.number_of_shards setting modified
Settings indexKnnSettings = Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, false).build();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't call this knn

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, SETTING_NUMBER_OF_SHARDS is not a bool setting so this would fail anyways.

@@ -164,7 +165,6 @@ public class RestoreService implements ClusterStateApplier {

private static final Set<String> USER_UNMODIFIABLE_SETTINGS = unmodifiableSet(
newHashSet(
SETTING_NUMBER_OF_SHARDS,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to do this to all of the settings in this list?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No particular reason, will add UnmodifiableOnRestore to those settings as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I think I see the confusion -- it looks like some of the existing index settings like INDEX_UUID_SETTING are not actually implemented as Setting so we can't use the property. Let's create a separate issue to track updating those settings that aren't settings and not take that up in the scope of this PR.

.setRenameReplacement(restoredIndex)
.get()
);
assertTrue(exception.getMessage().contains("cannot modify UnmodifiableOnRestore setting [index.number_of_shards]" + " on restore"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add some more test scenarios here? Off the top of my head:

  • Setting has unmodifiable on restore, but the setting is passed in to the request with the same value
  • Setting does not have unmodifiable on restore, we are able to modify the setting on restore
  • Some settings have unmodifiable on restore, still able to modify other settings

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing.

For the test cases below:

Setting has unmodifiable on restore, but the setting is passed in to the request with the same value

The existing behavior is that restore api will still throw a cannot modify error even if the setting has the same value. As long as there is a setting tagged as unmodifiable, restore will throw. I think it's more clean this way to not allow any unmodifiable settings in the request, to avoid unnecessary confusion for customers. Instead of including the same value as part of the request, just remove that setting from the request. I assume we would want to maintain that existing behavior?

Some settings have unmodifiable on restore, still able to modify other settings

For this test case, the existing behavior is that even if one of the settings in the restore request is unmodifiable, then restore will throw. I think it makes sense or else customers might think all the setting updates executed when some didn't. I assume we would want to maintain this behavior?

Thanks

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as a general rule of thumb we want to maintain the existing behavior (and that's why we're adding tests)

Copy link
Contributor

✅ Gradle check result for c29a0db: SUCCESS

Copy link
Contributor

❌ Gradle check result for a24b673: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@jed326
Copy link
Collaborator

jed326 commented Jan 17, 2025

❌ Gradle check result for a24b673: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

FYI @anntians these test failures seem to be due to test changes made in this PR

@anntians
Copy link
Author

Yes, I'm currently looking into the test failures

Signed-off-by: AnnTian Shao <[email protected]>
Copy link
Contributor

❌ Gradle check result for 252100c: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@@ -608,7 +608,7 @@ public void testTranslogGenerationSizeThreshold() {
}

public void testPrivateSettingsValidation() {
final Settings settings = Settings.builder().put(IndexMetadata.SETTING_CREATION_DATE, System.currentTimeMillis()).build();
final Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_UPGRADED, Version.V_EMPTY).build();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not change existing tests like this

@@ -164,7 +165,6 @@ public class RestoreService implements ClusterStateApplier {

private static final Set<String> USER_UNMODIFIABLE_SETTINGS = unmodifiableSet(
newHashSet(
SETTING_NUMBER_OF_SHARDS,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I think I see the confusion -- it looks like some of the existing index settings like INDEX_UUID_SETTING are not actually implemented as Setting so we can't use the property. Let's create a separate issue to track updating those settings that aren't settings and not take that up in the scope of this PR.

ExtensionScope,

/**
* Mark this setting as immutable on restore snapshot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: ... snapshot restore

@@ -1182,6 +1182,10 @@ public IndicesQueryCache getIndicesQueryCache() {
return indicesQueryCache;
}

public IndexScopedSettings getIndexScopedSettings() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add this API in MetadataCreateIndexService instead ? The IndicesService class is marked with @PublicAPi tag, so exposing anything from this class will be hard to hide it in future whereas MetadataCreateIndexService is internal.

@@ -91,6 +91,9 @@ public final class IndexScopedSettings extends AbstractScopedSettings {
MergeSchedulerConfig.MAX_MERGE_COUNT_SETTING,
MergeSchedulerConfig.MAX_THREAD_COUNT_SETTING,
IndexMetadata.SETTING_INDEX_VERSION_CREATED,
IndexMetadata.INDEX_UUID_SETTING,
IndexMetadata.SETTING_INDEX_CREATION_DATE,
IndexMetadata.SETTING_INDEX_HISTORY_UUID,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should avoid registering these internal settings to keep current behavior. I believe if user tries to update these internal setting, it will throw errors on the lines of unknown setting or something.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new settings added to IndexScopedSettings previously were not implemented as a Setting as noted in @jed326's #16957 (comment) as well. So the reason they're added to IndexScopedSettings is for the check

indexScopedSettings.isUnmodifiableOnRestoreSetting(k)

to work correctly, or else those settings will not be recognized because they're not registered as part of IndexScopedSettings.

I'm going to open a separate issue to update these settings with Setting implementation and add the UnmodifiableOnRestore setting.

However, there is a known issue with the SETTING_CREATION_DATE setting. The setting does have a Setting implementation, but it's in InternalSettingsPlugin.java. SETTING_CREATION_DATE setting also has several existing tests testCreationDateGivenFails and testPrivateSettingsValidation for enforcing its private/internal behavior. This means that if we add INDEX_CREATION_DATE_SETTING to IndexScopedSettings then both those tests will fail.

The way for the check

indexScopedSettings.isUnmodifiableOnRestoreSetting(k)

to work is if SETTING_CREATION_DATE setting is registered in IndexScopedSettings, which would require us to change/update the tests mentioned above. Unless there is another way to check a Setting's property without having to register that Setting to IndexScopedSettings?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, there is a known issue with the SETTING_CREATION_DATE setting. The setting does have a Setting implementation, but it's in InternalSettingsPlugin.java.

Why do we need to add this to IndexScopedSettings? InternalSettingsPlugin is just another plugin so it should be the same as any other index setting that is provided by a plugin.

Or put the opposite way, if this doesn't work for InternalSettingsPlugin then wouldn't it also not work for the knn (or any other) plugin?

/**
* Mark this setting as immutable on restore snapshot
*/
UnmodifiableOnRestore
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking can we use this property to enforce that settings defined with this property cannot be changed at all i.e. cannot be modified with a different value or cannot be also removed from the index. Currently we seem to handle only the modified part in RestoreService.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think @sohami raises a good point here that for example, having a setting with only UnmodifiableOnRestore but without Final probably doesn't make any sense because with only the former the setting could still be modified post restore.

On the other hand, I also think it's best to not have overlapping functionalities across the properties because that can also cause confusion.

AnnTian Shao added 2 commits January 21, 2025 15:20
This reverts commit 252100c.

Signed-off-by: AnnTian Shao <[email protected]>
Copy link
Contributor

❕ Gradle check result for 6dc9840: UNSTABLE

Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure.

Copy link
Contributor

❕ Gradle check result for e517731: UNSTABLE

Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure.

Copy link
Contributor

❌ Gradle check result for 9ebab5a: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants