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

txn: support read consistency read with ts checking #32922

Merged
merged 19 commits into from
Mar 16, 2022

Conversation

cfzjywxk
Copy link
Contributor

@cfzjywxk cfzjywxk commented Mar 8, 2022

What problem does this PR solve?

Issue Number: close #33159

Problem Summary:
Try to support the read-consistency read with tso checking optimization.

What is changed and how it works?

  • A new execution path for in-transaction read-consistency read is added, in which the first time execution last valid ts will be used as the for_update_ts. If the read check has failed, the select statement will be retried only if no result chunk has been sent back to the mysql client yet , a new global ts will be fetched doing retry.
  • A new system variable tidb_rc_read_check_ts is added to control whether the new path will be used, the default value is false.

Check List

Tests

  • Unit test

Side effects

Documentation

  • Affects user behaviors
  • Contains variable changes

Release note

Support the read-consistency read with ts checking optimization.

@cfzjywxk cfzjywxk added the sig/transaction SIG:Transaction label Mar 8, 2022
@cfzjywxk cfzjywxk requested a review from a team as a code owner March 8, 2022 12:25
@ti-chi-bot
Copy link
Member

ti-chi-bot commented Mar 8, 2022

[REVIEW NOTIFICATION]

This pull request has been approved by:

  • MyonKeminta
  • you06

To complete the pull request process, please ask the reviewers in the list to review by filling /cc @reviewer in the comment.
After your PR has acquired the required number of LGTMs, you can assign this pull request to the committer in the list by filling /assign @committer in the comment to help you merge this pull request.

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

Reviewer can indicate their review by submitting an approval review.
Reviewer can cancel approval by submitting a request changes review.

@ti-chi-bot ti-chi-bot added do-not-merge/needs-linked-issue release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Mar 8, 2022
@ti-chi-bot ti-chi-bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Mar 9, 2022
@@ -1849,6 +1849,17 @@ func (cc *clientConn) handleQuery(ctx context.Context, sql string) (err error) {
}
retryable, err = cc.handleStmt(ctx, stmt, parserWarns, i == len(stmts)-1)
if err != nil {
if retryable && cc.ctx.GetSessionVars().IsRcCheckTsRetryable(err) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If it's not retryable, will it raise an error to the client?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the write conflict error will be returned.

server/conn_stmt.go Outdated Show resolved Hide resolved
@@ -246,6 +246,8 @@ func (builder *RequestBuilder) SetFromSessionVars(sv *variable.SessionVars) *Req
}
if sv.StmtCtx.WeakConsistency {
builder.Request.IsolationLevel = kv.RC
} else if sv.StmtCtx.RCCheckTS {
builder.Request.IsolationLevel = kv.RCCheckTS
Copy link
Contributor

Choose a reason for hiding this comment

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

So weak consistency will override it, though both of them are barely used...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's ok to override if the tikv-rc is enabled as no transaction sematics is kept.

executor/executor.go Show resolved Hide resolved
sessionctx/variable/session.go Outdated Show resolved Hide resolved
if rcReadTS == 0 {
rcReadTS = b.ctx.GetSessionVars().TxnCtx.StartTS
}
return UpdateForUpdateTS(b.ctx, rcReadTS)
Copy link
Contributor

Choose a reason for hiding this comment

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

If rcReadTS != 0, do we need call UpdateForUpdateTS ? Can we optimize it to call UpdateForUpdateTS only once here ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Only SELECT statement call function refreshForUpdateTSForRC?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's expected to update the for_update_ts each time using the last valid read_ts. refreshForUpdateTSForRC will be used by write statements too in updateForUpdateTSIfNeeded.

@@ -1881,6 +1881,12 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) {
sc.NotFillCache = !opts.SQLCache
}
sc.WeakConsistency = isWeakConsistencyRead(ctx, stmt)
// Try to mark the `RCCheckTS` flag for the first time execution of in-transaction read requests
// using read-consistency isolation level.
if ctx.GetSessionVars().ConnectionID > 0 && ctx.GetSessionVars().RcReadCheckTS &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need add a transaction !AutoCommitTxn() && SelectCmd 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.

Select is already guaranteed in the above case condition. !AutoCommitTxn() is needed I'll add it.

@@ -156,6 +156,9 @@ func (e *PointGetExecutor) Open(context.Context) error {
} else {
e.snapshot = e.ctx.GetSnapshotWithTS(snapshotTS)
}
if e.ctx.GetSessionVars().StmtCtx.RCCheckTS {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why only PointGet and BatachPointGet need to process for RCCheckTS specially ?

Copy link
Contributor Author

@cfzjywxk cfzjywxk Mar 10, 2022

Choose a reason for hiding this comment

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

These cop executor builder will set the isolation flag but these two executors use txn snapshot directly.

server/conn.go Outdated Show resolved Hide resolved
server/conn.go Outdated Show resolved Hide resolved
return false
}
// The `RCCheckTS` flag of `stmtCtx` is reset d
return s.RcReadCheckTS && s.StmtCtx.RCCheckTS && errors.ErrorEqual(err, kv.ErrWriteConflict)
Copy link
Contributor

Choose a reason for hiding this comment

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

We reuse the error code kv.ErrWriteConflict, does it affect the write sqls behavior when write-conflict occur really.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This error is newly introduced to the SELECT statements I think it'll not affect the original write statment path.

Copy link
Contributor

Choose a reason for hiding this comment

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

May WriteConflict error be met during pessimistic lock phase when executing a DML statement, and then checked by this function?

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've added another condition judgement checking if it's read only statement.

@@ -977,6 +977,10 @@ func (worker *copIteratorWorker) handleCopResponse(bo *Backoffer, rpcCtx *tikv.R
zap.Uint64("regionID", task.region.GetID()),
zap.String("storeAddr", task.storeAddr),
zap.Error(err))
if strings.Contains(err.Error(), "write conflict") {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need add a limitation that is a "Rc Check Ts read" ? I mean whether some other scenes make a "write conflict" 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.

In the read path only the added path may return other error contains "write conflit", it's a bit difficult to visit stmtCtx here. Also the returned error will be checked if the retry could be done in the upper layer so maybe it's enough.

item, err := r.txn.Get(key)
if err != nil && err != badger.ErrKeyNotFound {
return nil, errors.Trace(err)
}
if item == nil {
return nil, nil
}
if r.RcCheckTS {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have any test case for this process?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The test in tidb_test.go would use mockstore and the path is covered there.

store/mockstore/unistore/tikv/dbreader/db_reader.go Outdated Show resolved Hide resolved
store/mockstore/unistore/tikv/mvcc.go Show resolved Hide resolved
if !isWriteLock {
return nil
}
return &kverrors.ErrConflict{
Copy link
Contributor

Choose a reason for hiding this comment

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

Whatever lock.startTS>=startTS or lock.startTS < startTS, if lock was not resloved, returns ErrConflict. Is it reasonable?
If lock was committed and lock.startTS<startTS, I think it should not return an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The read ts in RcCheckTS isolation level could be stale, so it could not be used to decide whether the lock could be skipped comparing ts.

@cfzjywxk
Copy link
Contributor Author

/run-all-tests

@ti-chi-bot ti-chi-bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 11, 2022
@ti-chi-bot ti-chi-bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 14, 2022
@cfzjywxk
Copy link
Contributor Author

Copy link
Contributor

@you06 you06 left a comment

Choose a reason for hiding this comment

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

rest LGTM

server/conn.go Outdated Show resolved Hide resolved
store/mockstore/unistore/tikv/dbreader/db_reader.go Outdated Show resolved Hide resolved
store/mockstore/unistore/tikv/dbreader/db_reader.go Outdated Show resolved Hide resolved
store/mockstore/unistore/tikv/mvcc.go Show resolved Hide resolved
@cfzjywxk
Copy link
Contributor Author

/merge

@cfzjywxk
Copy link
Contributor Author

/run-unit-test

@cfzjywxk cfzjywxk changed the title txn: support read consistency read with tso checking txn: support read consistency read with ts checking Mar 16, 2022
@cfzjywxk
Copy link
Contributor Author

/merge

Copy link
Member

@bb7133 bb7133 left a comment

Choose a reason for hiding this comment

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

LGTM

@bb7133
Copy link
Member

bb7133 commented Mar 16, 2022

/merge

@cfzjywxk
Copy link
Contributor Author

/run-unit-test

@cfzjywxk
Copy link
Contributor Author

/merge

@ti-chi-bot
Copy link
Member

@cfzjywxk: Your PR was out of date, I have automatically updated it for you.

At the same time I will also trigger all tests for you:

/run-all-tests

If the CI test fails, you just re-trigger the test that failed and the bot will merge the PR for you after the CI passes.

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 ti-community-infra/tichi repository.

@cfzjywxk
Copy link
Contributor Author

/merge

@ti-chi-bot ti-chi-bot merged commit d4d43ba into pingcap:master Mar 16, 2022
@cfzjywxk cfzjywxk deleted the rc_read_check_tso_retry branch March 16, 2022 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/transaction SIG:Transaction size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. status/can-merge Indicates a PR has been approved by a committer. status/LGT2 Indicates that a PR has LGTM 2.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

txn: support tso optimization for read-consistency isolation level read.
8 participants