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

table: fix wrong handle comparation in index double write #57418

Merged
merged 7 commits into from
Nov 19, 2024

Conversation

joechenrh
Copy link
Contributor

@joechenrh joechenrh commented Nov 15, 2024

What problem does this PR solve?

Issue Number: close #57414

Problem Summary:

What changed and how does it work?

Unlike other indices, global index encodes the value of its key-value pairs with a partition ID:

func genIndexValueVersion0(loc *time.Location, tblInfo *model.TableInfo, idxInfo *model.IndexInfo,
idxValNeedRestoredData bool, distinct bool, untouched bool, indexedValues []types.Datum, h kv.Handle,
partitionID int64, buf []byte) ([]byte, error) {
var idxVal []byte
if buf == nil {
idxVal = make([]byte, 0)
} else {
idxVal = buf[:0]
}
idxVal = append(idxVal, 0)
newEncode := false
tailLen := 0
if !h.IsInt() && distinct {
idxVal = encodeCommonHandle(idxVal, h)
newEncode = true
}
if idxInfo.Global {
idxVal = encodePartitionID(idxVal, partitionID)
newEncode = true
}

So during the double write process, we may do comparison between partition handles and non-partition handles.

if c.idxInfo.BackfillState != model.BackfillStateInapplicable {
// #52914: the delete key is covered by the new ingested key, which shouldn't be deleted.
originVal, err := getKeyInTxn(context.TODO(), txn, key)
if err != nil {
return err
}
if len(originVal) > 0 {
oh, err := tablecodec.DecodeHandleInIndexValue(originVal)
if err != nil {
return err
}
if !h.Equal(oh) {
okToDelete = false
}

For example, in #57414, h is the handle of global index i1 whose type is PartitionHandle while oh is IntHandle of the current index. Thus, !h.Equal(oh) will return false.

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 do-not-merge/needs-triage-completed release-note-none Denotes a PR that doesn't merit a release note. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Nov 15, 2024
Copy link

tiprow bot commented Nov 15, 2024

Hi @joechenrh. 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 Nov 15, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 75.2817%. Comparing base (2d9f829) to head (39b7b8b).
Report is 37 commits behind head on master.

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #57418        +/-   ##
================================================
+ Coverage   72.9476%   75.2817%   +2.3341%     
================================================
  Files          1672       1717        +45     
  Lines        461826     477452     +15626     
================================================
+ Hits         336891     359434     +22543     
+ Misses       104197      95757      -8440     
- Partials      20738      22261      +1523     
Flag Coverage Δ
integration 49.5796% <33.3333%> (?)
unit 72.4832% <100.0000%> (+0.1403%) ⬆️

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

Components Coverage Δ
dumpling 52.7673% <ø> (ø)
parser ∅ <ø> (∅)
br 61.8957% <ø> (+16.7700%) ⬆️
---- 🚨 Try these New Features:

@joechenrh
Copy link
Contributor Author

/ok-to-test

@ti-chi-bot ti-chi-bot bot added the ok-to-test Indicates a PR is ready to be tested. label Nov 15, 2024
@joechenrh joechenrh changed the title table: fix wrong handle comparation in index merge table: fix wrong handle comparation in index double write Nov 18, 2024
pkg/ddl/index_modify_test.go Outdated Show resolved Hide resolved
pkg/ddl/index.go Outdated Show resolved Hide resolved
@Defined2014 Defined2014 added the needs-cherry-pick-release-8.5 Should cherry pick this PR to release-8.5 branch. label Nov 18, 2024
@ti-chi-bot ti-chi-bot bot added the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label Nov 18, 2024
if !h.Equal(oh) {
// The handle passed in may be a `PartitionHandle`,
// so we can't directly do comparation with them.
if !handleEqual(h, oh) {
Copy link
Member

Choose a reason for hiding this comment

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

If the passed handle is PartaitionHandle, why oh isn't partitionHandle here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Take the case in #57414 as example, the handle h is retrieved from FetchDuplicatedHandle. Since global index is first checked and duplication is found, we will get PartitionHandle.

tidb/pkg/executor/insert.go

Lines 272 to 273 in 043f833

for _, uk := range r.uniqueKeys {
_, handle, err := tables.FetchDuplicatedHandle(ctx, uk.newKey, true, txn, e.Table.Meta().ID)

But the newly added index is not global index, so oh is just IntHandle.

In addition, there may also be opposite situations that oh is PartitionHandle and h is IntHandle. But IntHandle can be compared with PartitionHandle correctly.

@@ -386,6 +386,13 @@ func needPresumeKeyNotExistsFlag(ctx context.Context, txn kv.Transaction, key, t
return false, nil
}

func handleEqual(dupHandle, prevHandle kv.Handle) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we could change func (ph PartitionHandle) Equal(h Handle) bool function. Only both handles are partition handle, we need compare pid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe we could change func (ph PartitionHandle) Equal(h Handle) bool function.

I'm not sure if it will affect other code so I add a new function. Let me have a try.

Comment on lines -2027 to -2034
if idxInfo.Global {
// 'handle' comes from reading directly from a partition, without partition id,
// so we can only compare the handle part of the key.
if ph, ok := h.(kv.PartitionHandle); ok && ph.Handle.Equal(handle) {
// table row has been back-filled already, OK to add the index entry
return nil
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just remove some unnecessary logic for comparation.

Copy link

ti-chi-bot bot commented Nov 19, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Defined2014, 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 approved lgtm and removed needs-1-more-lgtm Indicates a PR needs 1 more LGTM. labels Nov 19, 2024
Copy link

ti-chi-bot bot commented Nov 19, 2024

[LGTM Timeline notifier]

Timeline:

  • 2024-11-18 06:22:13.185422736 +0000 UTC m=+855695.376291733: ☑️ agreed by Defined2014.
  • 2024-11-19 01:11:09.378685834 +0000 UTC m=+923431.569554816: ☑️ agreed by wjhuang2016.

@ti-chi-bot ti-chi-bot bot merged commit 058d947 into pingcap:master Nov 19, 2024
27 checks passed
@ti-chi-bot
Copy link
Member

In response to a cherrypick label: new pull request created to branch release-8.5: #57478.

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-8.5 Should cherry pick this PR to release-8.5 branch. ok-to-test Indicates a PR is ready to be tested. release-note-none Denotes a PR that doesn't merit a release note. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

INSERT ... ON DUPLICATE during index merge phase will cause data inconsistency
5 participants