Repository navigation
Fixes #35024: retry search update-by-query version conflicts against a refreshed index - #35027
Conversation
Code Review ✅ Approved 2 closed / 2 findings🔴 High risk · Changing retries for bulk search-index updates, including soft deletes and renames, could replay scripts incorrectly or leave many entity documents inconsistent. Adds ✅ 2 closed✅ Quality: Update-by-query conflict policy is stated only in the PR description
✅ Bug: Leftover-conflict warning always claims 3 attempts were made
VerificationRules No rules evaluated Functional validation Not enabledAuto-approval Not enabledFor more verification details, comment OptionsDisplay: compact → Showing compact verification results. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
Fixes #35024
Problem
Several changes update many search documents with one update-by-query: renaming a glossary term, tag or classification, moving a data product to another domain, changing a parent's fully qualified name, updating lineage or relationships, soft deleting or restoring a parent's children. If another write touches one of those documents during the scan, the engine reports a version conflict for it.
abort, so the first conflict stopped the update and every document after it kept its old value too.The database is right in every case; only search is wrong.
What this PR changes
UpdateByQueryReconciler, generalised fromColumnLineageReconciler(which did this for column lineage only), runs an update-by-query and reads its outcome. When there are version conflicts and the script is safe to run twice, it refreshes the target indices so the next attempt sees the latest documents, and tries again, at most 3 attempts in total. A script is not safe to replay when a second run would change an updated document again: renaming the prefixatoa.bis that case, becausea.bstill starts witha. Those run once.UpdateByQueryOutcomereports what is left after the last attempt: a warning with the operation, the indices, the count and the attempts made, or an error for real failures. When the caller knows the document ids, as the data product domain update does, they go to the search retry queue.The 12 synchronous update-by-query helpers of each engine now run through the reconciler, and all of them use
proceed.ColumnLineageReconcilerkeeps its behaviour and delegates to the shared code. The rule is recorded indocs/decisions/.What users will notice
Renames, domain moves, propagation and soft deletes that race with another edit reach every document they should. Anything still left behind is in the server log.
How it was tested
Unit tests for the reconciler (retries until clean, stops after 3 attempts, no retry when a replay is unsafe, refresh between attempts, leftovers reported) and for both engine managers (helpers retry on conflicts and use
proceed, the soft delete and restore of children included). The soft delete and restore suites pass on both engines (234 tests each).Integration suites for glossary terms, glossaries, classifications, tags, domains, data products, data product domain migration and lineage: 1,607 tests pass on OpenSearch. On Elasticsearch, one certification rename test failed once; it uses a background update this PR does not change and passed in two reruns.
Not in this PR
Child updates sent to the cluster as background tasks (
wait_for_completion=false): the server does not wait for those, so the request has nothing to retry.