Skip to content

Conversation

@tlrx
Copy link
Member

@tlrx tlrx commented Jul 12, 2021

Today if we try to shrink or to split a searchable snapshot index using the Resize API a new index will be created but can't be assigned, and even if it was assigned it won't work as the number of shards can't be changed and must always match the number of shards from the snapshot.

This pull request adds some verification to prevent a snapshot backed indices to be resized and if an attempt is made, throw a better error message.

Note that cloning is supported since #56595 and in this pull request we make sure that it is only used to convert the searchable snapshot index back to a regular index.

Relates #74977 (comment)

@tlrx tlrx added >enhancement :Distributed Coordination/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs v8.0.0 v7.15.0 labels Jul 12, 2021
@elasticmachine elasticmachine added the Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. label Jul 12, 2021
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-distributed (Team:Distributed)

@tlrx tlrx changed the title Prevent searchable snapshots indices to be shrunk/split/clone Prevent searchable snapshots indices to be shrunk/split Jul 12, 2021
Copy link
Contributor

@original-brownbear original-brownbear left a comment

Choose a reason for hiding this comment

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

LGTM, just a few optional nits :)

static void validateCloneIndex(ClusterState state, String sourceIndex, String targetIndexName, Settings targetIndexSettings) {
IndexMetadata sourceMetadata = validateResize(state, sourceIndex, targetIndexName, targetIndexSettings);
if ("snapshot".equals(INDEX_STORE_TYPE_SETTING.get(sourceMetadata.getSettings()))) {
for (Setting<?> nonCloneableSetting : List.of(INDEX_STORE_TYPE_SETTING, INDEX_RECOVERY_TYPE_SETTING)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: maybe use Arrays.asList() or some other thing that's JDK8 compatible to make the backport cleaner? :)

Copy link
Member Author

Choose a reason for hiding this comment

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

ok

IllegalArgumentException.class,
() -> client().admin().indices().prepareResizeIndex("mounted-index", "cloned-index").setResizeType(ResizeType.CLONE).get()
);
assertThat(
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: just assertEquals? (here and in other similar spots)

Copy link
Member Author

Choose a reason for hiding this comment

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

I do prefer the error messages returned by assertThat than assertEquals, if that's ok.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah sure :) didn't even know they were different :D

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm with Tanguy on this one, I find the argument order for assertEquals(expected, actual) confusing since it's the opposite to assertThat(actual, expectation).

@ESIntegTestCase.ClusterScope(numDataNodes = 1)
public class SearchableSnapshotsResizeIntegTests extends BaseFrozenSearchableSnapshotsIntegTestCase {

@Before
Copy link
Contributor

Choose a reason for hiding this comment

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

No need for this annotation I think, this is automatically called since the annotation is on the parent?

Copy link
Member Author

Choose a reason for hiding this comment

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

At least on my Intellij 2021.1.3 this is required for integ tests for JUnit to correctly set up the internal test cluster.

ensureGreen("mounted-index");
}

@After
Copy link
Contributor

Choose a reason for hiding this comment

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

No need for this annotation I think, this is automatically called since the annotation is on the parent?

.prepareResizeIndex("mounted-index", "shrunk-index")
.setResizeType(ResizeType.SHRINK)
.setSettings(
Settings.builder()
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: I added org.elasticsearch.snapshots.AbstractSnapshotIntegTestCase#indexSettingsNoReplicas at one point for this because it's such a common kind of setting in tests :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Forgot about this one, thanks!

.setResizeType(ResizeType.SPLIT)
.setSettings(
Settings.builder()
.put(INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: I added org.elasticsearch.snapshots.AbstractSnapshotIntegTestCase#indexSettingsNoReplicas at one point for this because it's such a common kind of setting in tests :)

Copy link
Contributor

@DaveCTurner DaveCTurner left a comment

Choose a reason for hiding this comment

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

I left a suggestion about avoiding repeated string literals, otherwise LGTM2.

*/
static List<String> validateShrinkIndex(ClusterState state, String sourceIndex, String targetIndexName, Settings targetIndexSettings) {
IndexMetadata sourceMetadata = validateResize(state, sourceIndex, targetIndexName, targetIndexSettings);
if ("snapshot".equals(INDEX_STORE_TYPE_SETTING.get(sourceMetadata.getSettings()))) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we move SearchableSnapshotsConstants#SNAPSHOT_DIRECTORY_FACTORY_KEY and SearchableSnapshotsConstants#isSearchableSnapshotStore to server rather than just using the literal "snapshot" throughout? Either that or add an independent constant in server and then add a static constructor to o.e.x.c.searchablesnapshots.SearchableSnapshotsConstants to assert that the constant in server is equal to SNAPSHOT_DIRECTORY_FACTORY_KEY?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I'll do something like this in a follow-up (it touches places outside of this pull request too)

Copy link
Contributor

@DaveCTurner DaveCTurner left a comment

Choose a reason for hiding this comment

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

A follow-up is fine with me; LGTM

@tlrx tlrx merged commit 4410d76 into elastic:master Jul 13, 2021
@tlrx tlrx deleted the forbid-resize-actions-for-ss branch July 13, 2021 10:33
@tlrx
Copy link
Member Author

tlrx commented Jul 13, 2021

Thanks Armin and David!

tlrx added a commit to tlrx/elasticsearch that referenced this pull request Jul 13, 2021
Today if we try to shrink or to split a searchable snapshot
index using the Resize API a new index will be created
but can't be assigned, and even if it was assigned it won't
work as the number of shards can't be changed and must
always match the number of shards from the snapshot.

This commit adds some verification to prevent a snapshot
backed indices to be resized and if an attempt is made,
throw a better error message.

Note that cloning is supported since elastic#56595 and in this
change we make sure that it is only used to convert the
searchable snapshot index back to a regular index.

Relates elastic#74977 (comment)
elasticsearchmachine pushed a commit that referenced this pull request Jul 13, 2021
)

Today if we try to shrink or to split a searchable snapshot
index using the Resize API a new index will be created
but can't be assigned, and even if it was assigned it won't
work as the number of shards can't be changed and must
always match the number of shards from the snapshot.

This commit adds some verification to prevent a snapshot
backed indices to be resized and if an attempt is made,
throw a better error message.

Note that cloning is supported since #56595 and in this
change we make sure that it is only used to convert the
searchable snapshot index back to a regular index.

Relates #74977 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Distributed Coordination/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs >enhancement Team:Distributed (Obsolete) Meta label for distributed team (obsolete). Replaced by Distributed Indexing/Coordination. v7.15.0 v8.0.0-alpha1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants