-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
executor: fix update ignore still report dup-key error in statement retry #54495
Conversation
Hi @lcwangchao. Thanks for your PR. PRs from untrusted users cannot be marked as trusted with 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. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #54495 +/- ##
=================================================
- Coverage 74.7741% 56.2582% -18.5159%
=================================================
Files 1539 1669 +130
Lines 361871 615209 +253338
=================================================
+ Hits 270586 346106 +75520
- Misses 71638 245607 +173969
- Partials 19647 23496 +3849
Flags with carried forward coverage won't be shown. Click here to find out more.
|
if err != nil { | ||
return err | ||
} | ||
err = t.rebuildIndices(sctx, txn, h, touched, oldData, newData, table.WithCtx(ctx)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why change these lines? The test still passes if these lines are unchanged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this code is unnecessary now. Deleting these lines can make code clear. The current LazyCheckKeyNotExists
is:
func (s *SessionVars) LazyCheckKeyNotExists() bool {
if s.StmtCtx.ErrGroupLevel(errctx.ErrGroupDupKey) != errctx.LevelError {
// This branch means we are in `insert/update ignore`.
// The executor will handle the dup-key error and ignore it in executor,
// so we must check the dup-key error in place to make sure the executor can get the error.
return false
}
return s.PresumeKeyNotExists || (s.TxnCtx != nil && s.TxnCtx.IsPessimistic)
}
You can see that if sessVars.TxnCtx.IsPessimistic
is true, s.PresumeKeyNotExists || (s.TxnCtx != nil && s.TxnCtx.IsPessimistic)
will always return true, we do not need to set PresumeKeyNotExists
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted diffs in LazyCheckKeyNotExists
can also fix this bug...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's go back to the original place. The purpose of tidb_constraint_check_in_place
is only to make the lazy unique index check for insert effective. Historically, only inserts had a lazy unique index check. tidb_constraint_check_in_place
was actually designed to remove this exclusive behavior for inserts, so that all statements execute consistent in-place checks. Therefore, update statements have never had a lazy check. So even if tidb_constraint_check_in_place
is off, updates should still report an error. @lcwangchao @ekexium
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for why the name was designed this way, that was the product manager's decision at the time. However, I don't think it's necessary to make updates lazy check as well. The reason insert needs lazy check is because it performs more efficiently during bulk loading. Bulk loading should rarely involve updates, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want the update to also perform a lazy check, handling it only at
tidb/pkg/table/tables/tables.go
Lines 579 to 589 in 08147e7
if !sessVars.InTxn() { | |
savePresumeKeyNotExist := sessVars.PresumeKeyNotExists | |
if !sessVars.ConstraintCheckInPlace && sessVars.TxnCtx.IsPessimistic { | |
sessVars.PresumeKeyNotExists = true | |
} | |
err = t.rebuildIndices(sctx, txn, h, touched, oldData, newData, table.WithCtx(ctx)) | |
sessVars.PresumeKeyNotExists = savePresumeKeyNotExist | |
if err != nil { | |
return err | |
} | |
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider a pessimistic txn, constraint_check_in_place=off, and error level is LevelWarn. In original code LazyCheckKeyNotExists
will return true, in this PR it will return false, right?
If we let the original value of vars.PresumeKeyNotExists
be !vars.ConstraintCheckInPlace
we will have the table:
InTxn | constraint_check_in_place | mode | levelError | master, lazy? | PR, lazy? | Equivalent |
---|---|---|---|---|---|---|
FALSE | FALSE | opt | FALSE | TRUE | FALSE | FALSE |
FALSE | FALSE | opt | TRUE | TRUE | TRUE | TRUE |
FALSE | FALSE | pes | FALSE | TRUE | FALSE | FALSE |
FALSE | FALSE | pes | TRUE | TRUE | TRUE | TRUE |
FALSE | TRUE | opt | FALSE | FALSE | FALSE | TRUE |
FALSE | TRUE | opt | TRUE | FALSE | FALSE | TRUE |
FALSE | TRUE | pes | FALSE | FALSE | FALSE | TRUE |
FALSE | TRUE | pes | TRUE | TRUE | TRUE | TRUE |
TRUE | FALSE | opt | FALSE | TRUE | FALSE | FALSE |
TRUE | FALSE | opt | TRUE | TRUE | TRUE | TRUE |
TRUE | FALSE | pes | FALSE | TRUE | FALSE | FALSE |
TRUE | FALSE | pes | TRUE | TRUE | TRUE | TRUE |
TRUE | TRUE | opt | FALSE | FALSE | FALSE | TRUE |
TRUE | TRUE | opt | TRUE | FALSE | FALSE | TRUE |
TRUE | TRUE | pes | FALSE | FALSE | FALSE | TRUE |
TRUE | TRUE | pes | TRUE | TRUE | TRUE | TRUE |
Besides, s.PresumeKeyNotExists
only makes the reasoning more complex. Since it's only set in one place, I think we should consider removing it.
This PR only changes Yes, I think |
So the correctness of this fix depends on how upper layer uses it. I suggest that we make |
/retest |
@lcwangchao: Cannot trigger testing until a trusted user reviews the PR and leaves an In response to this:
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. |
/retest |
@lcwangchao: Cannot trigger testing until a trusted user reviews the PR and leaves an In response to this:
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. |
/retest |
@lcwangchao: Cannot trigger testing until a trusted user reviews the PR and leaves an In response to this:
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. |
/retest |
@lcwangchao: Cannot trigger testing until a trusted user reviews the PR and leaves an In response to this:
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. |
/retest |
@lcwangchao: Cannot trigger testing until a trusted user reviews the PR and leaves an In response to this:
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you verified #20484? Seems the part was introduced to solve that issue.
Seems it is trying to make a lazy check for update... But I don't understand this PR, if a transaction is pessimistic and the statement is not @tiancaiamao could you PTAL? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current master branch does not work as expected.
If there is no begin
, the expected behavior is that index.Create
does not need tikvSnapshotGet to check unique key exist or not.
If there is a begin, both master branch and this PR don't use tikvSnapshotGet
under index.Create
:
This PR does not make thing change, and it simplify the logic, so LGTM
As for why the current master branch does not work as expected, we can take a separate thread to trace...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's difficult to verify the correctness for all the combinations of optimistic/pessimistic mods and check in-place or not directly.
We may need to file a refactor and test coverage task to clarify the related code path, especially the optimistic mode
would be deprecated in the future. It could be also considered as one of the sub-tasks of the deprecation.
/cc @lcwangchao @ekexium
@cfzjywxk: GitHub didn't allow me to request PR reviews from the following users: lcwangchao. Note that only pingcap members and repo collaborators can review this PR, and authors cannot review their own PRs. In response to this:
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/test-infra repository. |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: cfzjywxk, tiancaiamao 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 |
[LGTM Timeline notifier]Timeline:
|
What problem does this PR solve?
Issue Number: close #54489
What changed and how does it work?
Check List
Tests
Side effects
Documentation
Release note
Please refer to Release Notes Language Style Guide to write a quality release note.