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

[Migrations] Only pickup updated SO types when performing a compatible migration #159962

Merged
merged 12 commits into from
Jun 30, 2023

Conversation

gsoldevila
Copy link
Contributor

@gsoldevila gsoldevila commented Jun 19, 2023

Summary

Tackles the first improvement described in #160038.

When "picking up" the updated mappings, we add a "query" in order to select and update only the SO types that have been updated, compared to the previous version.

We achieve this by comparing migrationMappingPropertyHashes; we compare the hashes stored in the <soIndex>.mapping._meta.migrationMappingPropertyHashes against the ones calculated from the definitions from the typeRegistry.

@gsoldevila gsoldevila added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc enhancement New value added to drive a business result release_note:skip Skip the PR/issue when compiling release notes Feature:Migrations backport:prev-minor Backport to (8.x) the previous minor version (i.e. one version back from main) v8.9.0 v8.8.2 labels Jun 19, 2023
@gsoldevila gsoldevila marked this pull request as ready for review June 20, 2023 16:01
@gsoldevila gsoldevila requested a review from a team as a code owner June 20, 2023 16:01
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

@gsoldevila
Copy link
Contributor Author

@pgayvallet I believe it makes sense to add this enhancement to the ZDT as well, right?

Copy link
Contributor

@rudolf rudolf left a comment

Choose a reason for hiding this comment

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

Left some nits, but biggest question is around getUpdatedHashes(...) when actual doesn't have a _meta

@@ -35,7 +36,8 @@ export const pickupUpdatedMappings =
(
client: ElasticsearchClient,
index: string,
batchSize: number
batchSize: number,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit on line 23 the comment says:

Pickup updated mappings by performing an update by query operation on all documents in the index. Returns a task ID which can be tracked for progress.

maybe we can update that to be "on all documents matching the passed in query"

...stateP.logs,
{
level: 'info',
message: `Kibana is performing a compatible update and some root fields have been updated. All SO documents must be updated. Updated root fields: ${nonTypeFields}.`,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
message: `Kibana is performing a compatible update and some root fields have been updated. All SO documents must be updated. Updated root fields: ${nonTypeFields}.`,
message: `Kibana is performing a compatible upgrade and the mappings of some root fields have been changed. For Elasticsearch to pickup these mappings, all saved objects need to be updated. Updated root fields: ${nonTypeFields}.`,

Thought it's useful to explain the "pickup updated mappings" part similar to what you did in the log message below.

properties: {},
};

expect(getUpdatedHashes(actual, expected)).toBeUndefined();
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 unsure about this. Probably an edge case but if an index doesn't have _meta can we safely conclude that all mappings have been picked up? Feels safer to assume all types' mappings have changed and need pickup?

Having getUpdatedHashes(...): string[] | undefined is also a slightly awkward API where undefined means something like "I don't know"...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, when this method returns undefined we don't pass in a query, so we already update all types.
But you've got a point, this can be confusing.
I'll update the logic to not rely on this undefined.

// some top-level properties have changed, e.g. 'dynamic' or '_meta' (see diffMappings())
return {
...stateP,
controlState: 'UPDATE_TARGET_MAPPINGS_PROPERTIES',
Copy link
Contributor

Choose a reason for hiding this comment

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

If when actual._meta === undefined we say "all types have changed" instead of undefined (see my other comment) then we could only end up here if we change dynamic right? I'm wondering a bit if this scenario could ever happen in the wild?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wasn't sure about the dynamic case, so I played it safe and updated everything in that case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After some investigation, it seems that for target indices we have dynamic: 'strict' and for temporary (and cloned) indices we have dynamic: false.

So if a migrator fails before the UPDATE_TARGET_MAPPINGS_PROPERTIES step, the corresponding index would still have the dynamic: false. However it would be missing the hashes and the indexTypesMap as well, which already trigger a "full" pickup of documents.

TLDR: It can happen and we must pickup all documents in that case.

Copy link
Contributor Author

@gsoldevila gsoldevila Jun 28, 2023

Choose a reason for hiding this comment

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

I improved the code with this commit, I think it is much more clear now.

@gsoldevila gsoldevila requested a review from rudolf June 28, 2023 12:36
Copy link
Contributor

@rudolf rudolf left a comment

Choose a reason for hiding this comment

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

Left a nit on a comment that confused me, but implementation looks good 👍

],
};
} else {
// compatible migration, all updated hashes correspond to SO types
Copy link
Contributor

Choose a reason for hiding this comment

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

all updated hashes correspond to SO types

This sounds a lot to me like "The md5 of ALL mappings match, so there's no need to update target mappings" should this maybe be "some hashes are different because of changes in saved object type's mappings"

@gsoldevila gsoldevila added v8.10.0 and removed v8.8.2 labels Jun 30, 2023
@gsoldevila gsoldevila enabled auto-merge (squash) June 30, 2023 13:27
@gsoldevila gsoldevila merged commit 6f87e1d into elastic:main Jun 30, 2023
@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/core-saved-objects-migration-server-internal 89 90 +1
Unknown metric groups

API count

id before after diff
@kbn/core-saved-objects-migration-server-internal 123 124 +1

ESLint disabled line counts

id before after diff
enterpriseSearch 14 16 +2
securitySolution 413 417 +4
total +6

Total ESLint disabled count

id before after diff
enterpriseSearch 15 17 +2
securitySolution 492 496 +4
total +6

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Jun 30, 2023
…e migration (elastic#159962)

## Summary

Tackles the first improvement described in
elastic#160038.

When "picking up" the updated mappings, we add a "query" in order to
select and update only the SO types that have been updated, compared to
the previous version.

We achieve this by comparing `migrationMappingPropertyHashes`; we
compare the hashes stored in the
`<soIndex>.mapping._meta.migrationMappingPropertyHashes` against the
ones calculated from the definitions from the `typeRegistry`.

---------

Co-authored-by: kibanamachine <[email protected]>
(cherry picked from commit 6f87e1d)
@kibanamachine
Copy link
Contributor

💚 All backports created successfully

Status Branch Result
8.9

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Jun 30, 2023
…patible migration (#159962) (#161010)

# Backport

This will backport the following commits from `main` to `8.9`:
- [[Migrations] Only pickup updated SO types when performing a
compatible migration
(#159962)](#159962)

<!--- Backport version: 8.9.7 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Gerard
Soldevila","email":"[email protected]"},"sourceCommit":{"committedDate":"2023-06-30T14:40:40Z","message":"[Migrations]
Only pickup updated SO types when performing a compatible migration
(#159962)\n\n## Summary\r\n\r\nTackles the first improvement described
in\r\nhttps://github.com//issues/160038.\r\n\r\nWhen
\"picking up\" the updated mappings, we add a \"query\" in order
to\r\nselect and update only the SO types that have been updated,
compared to\r\nthe previous version.\r\n\r\nWe achieve this by comparing
`migrationMappingPropertyHashes`; we\r\ncompare the hashes stored in
the\r\n`<soIndex>.mapping._meta.migrationMappingPropertyHashes` against
the\r\nones calculated from the definitions from the
`typeRegistry`.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>","sha":"6f87e1d6960ee4ac48908c7bef75b00abca265cb","branchLabelMapping":{"^v8.10.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Core","enhancement","release_note:skip","Feature:Migrations","backport:prev-minor","v8.9.0","v8.10.0"],"number":159962,"url":"https://github.com/elastic/kibana/pull/159962","mergeCommit":{"message":"[Migrations]
Only pickup updated SO types when performing a compatible migration
(#159962)\n\n## Summary\r\n\r\nTackles the first improvement described
in\r\nhttps://github.com//issues/160038.\r\n\r\nWhen
\"picking up\" the updated mappings, we add a \"query\" in order
to\r\nselect and update only the SO types that have been updated,
compared to\r\nthe previous version.\r\n\r\nWe achieve this by comparing
`migrationMappingPropertyHashes`; we\r\ncompare the hashes stored in
the\r\n`<soIndex>.mapping._meta.migrationMappingPropertyHashes` against
the\r\nones calculated from the definitions from the
`typeRegistry`.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>","sha":"6f87e1d6960ee4ac48908c7bef75b00abca265cb"}},"sourceBranch":"main","suggestedTargetBranches":["8.9"],"targetPullRequestStates":[{"branch":"8.9","label":"v8.9.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.10.0","labelRegex":"^v8.10.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/159962","number":159962,"mergeCommit":{"message":"[Migrations]
Only pickup updated SO types when performing a compatible migration
(#159962)\n\n## Summary\r\n\r\nTackles the first improvement described
in\r\nhttps://github.com//issues/160038.\r\n\r\nWhen
\"picking up\" the updated mappings, we add a \"query\" in order
to\r\nselect and update only the SO types that have been updated,
compared to\r\nthe previous version.\r\n\r\nWe achieve this by comparing
`migrationMappingPropertyHashes`; we\r\ncompare the hashes stored in
the\r\n`<soIndex>.mapping._meta.migrationMappingPropertyHashes` against
the\r\nones calculated from the definitions from the
`typeRegistry`.\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>","sha":"6f87e1d6960ee4ac48908c7bef75b00abca265cb"}}]}]
BACKPORT-->

Co-authored-by: Gerard Soldevila <[email protected]>
gsoldevila added a commit that referenced this pull request Jul 4, 2023
Part of #161067

Same idea as #159962, but applied
to ZDT.

When "picking up" the updated mappings, we add a "query" in order to
select and update only the SO types that have been updated, compared to
the previous version.
@rudolf rudolf added the Epic:ScaleMigrations Scale upgrade migrations to millions of saved objects label Sep 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:prev-minor Backport to (8.x) the previous minor version (i.e. one version back from main) enhancement New value added to drive a business result Epic:ScaleMigrations Scale upgrade migrations to millions of saved objects Feature:Migrations release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v8.9.0 v8.10.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants