Skip to content

Conversation

tangenta
Copy link
Contributor

What problem does this PR solve?

Issue Number: close #60339

Problem Summary: See #60339 (comment)

What changed and how does it work?

Always append temp index values during DML execution for unique indexes.

Check List

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No need to test
    • I checked and no code files have been changed.

Side effects

  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Breaking backward compatibility

Documentation

  • Affects user behaviors
  • Contains syntax changes
  • Contains variable changes
  • Contains experimental features
  • Changes MySQL compatibility

Release note

Please refer to Release Notes Language Style Guide to write a quality release note.

None

@ti-chi-bot ti-chi-bot bot added release-note-none Denotes a PR that doesn't merit a release note. do-not-merge/needs-triage-completed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Mar 31, 2025
Copy link

tiprow bot commented Mar 31, 2025

Hi @tangenta. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Copy link

codecov bot commented Mar 31, 2025

Codecov Report

Attention: Patch coverage is 70.00000% with 21 lines in your changes missing coverage. Please review.

Project coverage is 75.3565%. Comparing base (d916614) to head (3d75a51).
Report is 553 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #60340        +/-   ##
================================================
+ Coverage   73.1301%   75.3565%   +2.2264%     
================================================
  Files          1710       1761        +51     
  Lines        472671     497731     +25060     
================================================
+ Hits         345665     375073     +29408     
+ Misses       105751     100039      -5712     
- Partials      21255      22619      +1364     
Flag Coverage Δ
integration 49.1831% <15.7142%> (?)
unit 72.7387% <70.0000%> (+0.4101%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 52.6553% <ø> (-0.0357%) ⬇️
parser ∅ <ø> (∅)
br 61.9065% <ø> (+14.7142%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

// For temp index keys, we can't get the temp value from memory buffer, even if the lazy check is enabled.
// Otherwise, it may cause the temp index value to be overwritten, leading to data inconsistency.
value, err = txn.Get(ctx, key)
Copy link
Member

Choose a reason for hiding this comment

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

Is the 'key' here tempKey or not?
If it is, txn, get (ctx, tempKey) is a duplicated operation.
It may be confusing here.

Copy link
Contributor

Choose a reason for hiding this comment

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

As I understand it, if keyIsTempIdxKey is true, then key is actually the temporary index key (and tempKey is nil), otherwise key is the original new index and tempKey the temporary index key (for the same entry).
So we need to check both the original (currently backfilling/merging) key as well as the temporary index key, to see if the entry/key already exists.

@tangenta could we do these checks lazily/GetLocal(), and adding kv.SetPresumeKeyNotExists to key/tempKey?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I think we cannot utilize "needPresumeKeyExists" because using this constraint means that we already know where the previous record is. Without geting both original index and temp index, we don't know if there is a duplicate one.

Copy link
Contributor

@mjonss mjonss left a comment

Choose a reason for hiding this comment

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

I'm reviewing this mostly so I can learn something myself :)
So I have some questions, also about surrounding code.

I guess that my only concern is if we are adding txn.Get() calls, which may cause duplicate calls with the same key in some cases? Or will this only touch the local membuffer, so impact is neglectible?

@@ -292,6 +292,7 @@ func (c *index) create(sctx table.MutateContext, txn kv.Transaction, indexedValu
}
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 trying to understand the use of temporary index, I assume it is only used during ingest/fast_ddl/lightning way of creating indexes, so the original new index id would be written by the backfill and the original new index id + TempIndexPrefix would be used by concurrent DML, until the the backfill is done and change the indexInfo.State from model.BackfillStateRunning to model.BackfillStateReadyToMerge or even model.BackfillStateMerging.

The first question would then be at line 206, if the index state is in StateDeleteOnly/keyVer == tablecodec.TempIndexKeyTypeDelete, why would we even continue with the create() and not just skip it, since I assume it should not Set any index entries? (That would happen in (*index) Delete() right?

Second question at line 258, can a keyIsTmpIdxKey/tmpKey be untouched? Should we not always create/write keys to temp index or are they actually checked before the call?
I'm curious if this could lead to missing an index entry from concurrent DML during backfill, when the backfill already read the row.

And at line 273, during merge, the key needs to be double written, both to the original new index, as well as the temporary index, since we cannot know if that specific key has already been merged yet or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

why would we even continue with the create() and not just skip it

I remember there is a case could cause correctness issue but I forget the details. Let me file another PR to see if CI can pass.

can a keyIsTmpIdxKey/tmpKey be untouched?

No, untouched key-values only exist in membuffer, they are not persistent. Untouched key-values are only used for read request like union scan, but temp index is not public.

@@ -366,7 +376,7 @@ func (c *index) create(sctx table.MutateContext, txn kv.Transaction, indexedValu
}
if len(tempKey) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe also add a new comment on line 357, that needPresumeKeyNotExistsFlag will check either the temp index key (if used) or the key, by a Get()?
Also why is it really needing the c.tblInfo.ID, which is already encoded in both key and tempKey?

@tangenta does this mean that we may do the Get() twice now for the same key with the addition of Get() on line 326 and 329?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now I remove needPresumeKeyNotExistsFlag. For temp keys, we only call Get() once.

// For temp index keys, we can't get the temp value from memory buffer, even if the lazy check is enabled.
// Otherwise, it may cause the temp index value to be overwritten, leading to data inconsistency.
value, err = txn.Get(ctx, key)
Copy link
Contributor

Choose a reason for hiding this comment

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

As I understand it, if keyIsTempIdxKey is true, then key is actually the temporary index key (and tempKey is nil), otherwise key is the original new index and tempKey the temporary index key (for the same entry).
So we need to check both the original (currently backfilling/merging) key as well as the temporary index key, to see if the entry/key already exists.

@tangenta could we do these checks lazily/GetLocal(), and adding kv.SetPresumeKeyNotExists to key/tempKey?

@Benjamin2037 Benjamin2037 added the needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. label Apr 10, 2025
@Benjamin2037
Copy link
Collaborator

/retest

@ti-chi-bot ti-chi-bot bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Apr 15, 2025
@tangenta
Copy link
Contributor Author

/retest

Copy link

tiprow bot commented Apr 15, 2025

@tangenta: Cannot trigger testing until a trusted user reviews the PR and leaves an /ok-to-test message.

In response to this:

/retest

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot ti-chi-bot bot added approved needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Apr 15, 2025
assert.NoError(t, err)
}

require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/ddl/skipReorgWorkForTempIndex", "return(false)"))
Copy link
Contributor

Choose a reason for hiding this comment

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

You might be able to use testfailpoint pkg instead of the error checks + cleanup for failpoint pkg.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Trying to make it easier to cherry-pick :)

Copy link

ti-chi-bot bot commented Apr 15, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mjonss, wjhuang2016

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot bot added lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Apr 15, 2025
Copy link

ti-chi-bot bot commented Apr 15, 2025

[LGTM Timeline notifier]

Timeline:

  • 2025-04-15 08:45:37.010201628 +0000 UTC m=+2764430.694437724: ☑️ agreed by wjhuang2016.
  • 2025-04-15 12:42:31.533869532 +0000 UTC m=+2778645.218105624: ☑️ agreed by mjonss.

@mjonss
Copy link
Contributor

mjonss commented Apr 15, 2025

/retest

Copy link

tiprow bot commented Apr 15, 2025

@mjonss: Cannot trigger testing until a trusted user reviews the PR and leaves an /ok-to-test message.

In response to this:

/retest

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@tangenta
Copy link
Contributor Author

/retest

Copy link

tiprow bot commented Apr 15, 2025

@tangenta: Cannot trigger testing until a trusted user reviews the PR and leaves an /ok-to-test message.

In response to this:

/retest

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@tangenta
Copy link
Contributor Author

/retest

Copy link

tiprow bot commented Apr 15, 2025

@tangenta: Cannot trigger testing until a trusted user reviews the PR and leaves an /ok-to-test message.

In response to this:

/retest

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@joccau
Copy link
Contributor

joccau commented Apr 16, 2025

/test pull-lightning-integration-test

Copy link

tiprow bot commented Apr 16, 2025

@joccau: The specified target(s) for /test were not found.
The following commands are available to trigger required jobs:

  • /test fast_test_tiprow
  • /test tidb_parser_test

Use /test all to run all jobs.

In response to this:

/test pull-lightning-integration-test

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot ti-chi-bot bot merged commit 2a5047b into pingcap:master Apr 16, 2025
27 checks passed
ti-chi-bot pushed a commit to ti-chi-bot/tidb that referenced this pull request Apr 16, 2025
@ti-chi-bot
Copy link
Member

In response to a cherrypick label: new pull request created to branch release-8.5: #60590.
But this PR has conflicts, please resolve them!

zeminzhou pushed a commit to zeminzhou/tidb that referenced this pull request May 6, 2025
River2000i pushed a commit to River2000i/tidb that referenced this pull request Jun 17, 2025
@Benjamin2037 Benjamin2037 added needs-cherry-pick-release-7.5 Should cherry pick this PR to release-7.5 branch. needs-cherry-pick-release-8.1 Should cherry pick this PR to release-8.1 branch. labels Jul 2, 2025
ti-chi-bot pushed a commit to ti-chi-bot/tidb that referenced this pull request Jul 2, 2025
@ti-chi-bot
Copy link
Member

In response to a cherrypick label: new pull request created to branch release-8.1: #62148.
But this PR has conflicts, please resolve them!

ti-chi-bot pushed a commit to ti-chi-bot/tidb that referenced this pull request Jul 2, 2025
@ti-chi-bot
Copy link
Member

In response to a cherrypick label: new pull request created to branch release-7.5: #62149.
But this PR has conflicts, please resolve them!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved lgtm needs-cherry-pick-release-7.5 Should cherry pick this PR to release-7.5 branch. needs-cherry-pick-release-8.1 Should cherry pick this PR to release-8.1 branch. needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. release-note-none Denotes a PR that doesn't merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Data inconsistent after adding unique index
6 participants