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

Snapshot of a searchable snapshot should be empty #66162

Conversation

DaveCTurner
Copy link
Contributor

Today if you take a snapshot of a searchable snapshot index then we
treat it like a normal index and copy (any unchanged parts of) its
contents the the repository. This is often a complete copy, doubling the
snapshot storage required, since a searchable snapshot index typically
has a different name from the original index; it may also be that we are
taking a snapshot into a different repository. The content of a
searchable snapshot is already held in a snapshot, and its index
metadata indicates how to find this content, so it is wasteful to copy
anything new into the repository.

This commit adjusts things so that a searchable snapshot shard presents
itself to the snapshotter as if it contained no segments, and adjusts
things to account for the consequent mismatch at restore time.

Closes #66110

Today if you take a snapshot of a searchable snapshot index then we
treat it like a normal index and copy (any unchanged parts of) its
contents the the repository. This is often a complete copy, doubling the
snapshot storage required, since a searchable snapshot index typically
has a different name from the original index; it may also be that we are
taking a snapshot into a different repository. The content of a
searchable snapshot is already held in a snapshot, and its index
metadata indicates how to find this content, so it is wasteful to copy
anything new into the repository.

This commit adjusts things so that a searchable snapshot shard presents
itself to the snapshotter as if it contained no segments, and adjusts
things to account for the consequent mismatch at restore time.

Closes elastic#66110
@DaveCTurner DaveCTurner added >bug :Distributed Coordination/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs v8.0.0 v7.11.0 labels Dec 10, 2020
@elasticmachine elasticmachine added the Team:Distributed Meta label for distributed team (obsolete) label Dec 10, 2020
@elasticmachine
Copy link
Collaborator

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

@DaveCTurner
Copy link
Contributor Author

I can't decide whether I think this is an elegant solution or an awful hack :) Probably best to assume the latter when reviewing it, and think about ways this might come back to haunt us in the future.

final Directory directory = engineConfig.getStore().directory();
final String oldestSegmentsFile = Arrays.stream(directory.listAll())
.filter(s -> s.startsWith(IndexFileNames.SEGMENTS + "_"))
.min(Comparator.naturalOrder())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, this will almost always work except for cases where we add another character to the encoded generation (think "1" < "10" < "2"). I'll address this.

Copy link
Member

@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.

I think if we want to go for a hack this is the shortest possible one pretty much :)
I'm +1 to this approach, it's somewhat similar to how we hack around things in the recovery and I like how it's pretty risk free by not changing anything of substance about the snapshot process.

Just one open question + tests seem to fail

Copy link
Member

@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 thanks David!

Copy link
Contributor

@henningandersen henningandersen left a comment

Choose a reason for hiding this comment

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

Did an initial read and have a couple of suggestions.

@Override
public IndexCommitRef acquireIndexCommitForSnapshot() throws EngineException {
store.incRef();
return new IndexCommitRef(emptyIndexCommit, store::decRef);
Copy link
Contributor

Choose a reason for hiding this comment

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

If we can skip the restore completely (see previous comment), could we then instead return null here and also skip the snapshotting completely?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not trivially, no, we want the snapshot of this shard to succeed (without having done much) so we can't just bail out, and we use a null commit to indicate "find the latest commit" further down the line.

@DaveCTurner
Copy link
Contributor Author

I'm not merging this quite yet because it doesn't account for frozen indices: in the frozen case, we don't use the ReadOnlyEngine with the customisations introduced here.

@DaveCTurner
Copy link
Contributor Author

darn it, also doesn't account for closed indices, which we hard-code to have a NoOpEngine that supports proper snapshotting 😢

@DaveCTurner DaveCTurner dismissed original-brownbear’s stale review December 10, 2020 16:53

needs more work for the frozen/closed case

@DaveCTurner
Copy link
Contributor Author

I have adjusted how this PR injects the searchable-snapshots-specific snapshotting behaviour to avoid having it depend on the engine implementation directly, since we cannot control this in the frozen/closed case.

I've elected to re-use the index.store.type setting for this customisation rather than to introduce a new setting.

Copy link
Contributor

@henningandersen henningandersen left a comment

Choose a reason for hiding this comment

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

LGTM.

@DaveCTurner
Copy link
Contributor Author

@elasticmachine please run elasticsearch-ci/2

Process 'Gradle Test Executor 400' finished with non-zero exit value 1

@DaveCTurner DaveCTurner merged commit 69e5ea1 into elastic:master Dec 14, 2020
DaveCTurner added a commit that referenced this pull request Dec 14, 2020
Today if you take a snapshot of a searchable snapshot index then we
treat it like a normal index and copy (any unchanged parts of) its
contents the the repository. This is often a complete copy, doubling the
snapshot storage required, since a searchable snapshot index typically
has a different name from the original index; it may also be that we are
taking a snapshot into a different repository. The content of a
searchable snapshot is already held in a snapshot, and its index
metadata indicates how to find this content, so it is wasteful to copy
anything new into the repository.

This commit adjusts things so that a searchable snapshot shard presents
itself to the snapshotter as if it contained no segments, and adjusts
things to account for the consequent mismatch at restore time.

Closes #66110
jasontedor added a commit to jasontedor/elasticsearch that referenced this pull request Dec 14, 2020
* elastic/master: (33 commits)
  Add searchable snapshot cache folder to NodeEnvironment (elastic#66297)
  [DOCS] Add dynamic runtime fields to docs (elastic#66194)
  Add HDFS searchable snapshot integration (elastic#66185)
  Support canceling cross-clusters search requests (elastic#66206)
  Mute testCacheSurviveRestart (elastic#66289)
  Fix cat tasks api params in spec and handler (elastic#66272)
  Snapshot of a searchable snapshot should be empty (elastic#66162)
  [ML] DFA _explain API should not fail when none field is included (elastic#66281)
  Add action to decommission legacy monitoring cluster alerts (elastic#64373)
  move rollup_index param out of RollupActionConfig (elastic#66139)
  Improve FieldFetcher retrieval of fields (elastic#66160)
  Remove unsed fields in `RestAnalyzeAction` (elastic#66215)
  Simplify searchable snapshot CacheKey (elastic#66263)
  Autoscaling remove feature flags (elastic#65973)
  Improve searchable snapshot mount time (elastic#66198)
  [ML] Report cause when datafeed extraction encounters error (elastic#66167)
  Remove suggest reference in some API specs (elastic#66180)
  Fix warning when installing a plugin for different ESversion (elastic#66146)
  [ML] make `xpack.ml.max_ml_node_size` and `xpack.ml.use_auto_machine_memory_percent` dynamically settable (elastic#66132)
  [DOCS] Add `require_alias` to Bulk API (elastic#66259)
  ...
@DaveCTurner DaveCTurner removed the WIP label Feb 1, 2021
@DaveCTurner DaveCTurner deleted the 2020-12-09-snapshotting-searchable-snapshots branch February 1, 2021 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :Distributed Coordination/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs Team:Distributed Meta label for distributed team (obsolete) v7.11.0 v8.0.0-alpha1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Snapshots of mounted indices do not reuse the recovery source of the mounted index
5 participants