-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
tikv/txn: support local latch in transaction #6418
Conversation
store/tikv/txn.go
Outdated
if err == nil { | ||
commitTS = committer.commitTS | ||
} | ||
txn.store.txnLatches.UnLock(lock, commitTS) |
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 commitTS
is not used in UnLock
.
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.
Can we put commitTS
into lock
?
store/tikv/latch/scheduler.go
Outdated
@@ -85,6 +85,7 @@ func (scheduler *LatchesScheduler) Lock(startTS uint64, keys [][]byte) *Lock { | |||
|
|||
// UnLock unlocks a lock with commitTS. | |||
func (scheduler *LatchesScheduler) UnLock(lock *Lock, commitTS uint64) { | |||
lock.commitTS = commitTS |
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.
We can remove the argument, and set commitTS
before UnLock
.
store/tikv/kv.go
Outdated
@@ -165,7 +168,7 @@ func (s *tikvStore) CheckVisibility(startTime uint64) error { | |||
return nil | |||
} | |||
|
|||
func newTikvStore(uuid string, pdClient pd.Client, spkv SafePointKV, client Client, enableGC bool) (*tikvStore, error) { | |||
func newTikvStore(uuid string, pdClient pd.Client, spkv SafePointKV, client Client, enableGC, enableTxnLocalLatches bool) (*tikvStore, error) { |
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 are too many arguments to new TiKVStore.
Can we remove enableGC
and enableTxnLocalLatches
, and set them in a method when we want the non-default value?
@AndreMouche |
@lamxTyler PTAL |
sessionctx/context.go
Outdated
return context.WithValue(ctx, Retryable, retryAble) | ||
} | ||
|
||
// GetRetryable returns the value of GetRetryable from the 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.
value of retryable.
sessionctx/context.go
Outdated
|
||
// GetRetryable returns the value of GetRetryable from the ctx. | ||
func GetRetryable(ctx context.Context) bool { | ||
var retryAble bool |
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.
I think there is no need to capitalize the a
.
store/tikv/2pc.go
Outdated
err := c.execute(ctx) | ||
if err != nil { | ||
c.writeFinishBinlog(binlog.BinlogType_Rollback, 0) | ||
|
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.
redundant blank line.
store/tikv/txn.go
Outdated
// for transactions not retryable, commit directly. | ||
if !sessionctx.GetRetryable(ctx) { | ||
err = committer.executeAndWriteFinishBinlog(ctx) | ||
txn.store.txnLatches.RefreshCommitTS(committer.keys, committer.startTS) |
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 use the startTS
to refresh? Can we refresh if an error occurred when commit?
@@ -185,20 +184,41 @@ func (txn *tikvTxn) Commit(ctx context.Context) error { | |||
connID = val.(uint64) | |||
} | |||
committer, err := newTwoPhaseCommitter(txn, connID) | |||
if err != nil { | |||
if err != nil || committer == nil { |
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.
When will commiter == nil
? and if it's really nil, the error trace would be oddly.
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.
When no row needs to update in this transaction.
sessionctx/context.go
Outdated
const Retryable contextKey = "Retryable" | ||
|
||
// SetCommitCtx sets the variables for context before commit a transaction. | ||
func SetCommitCtx(ctx context.Context, sessCtx Context) context.Context { |
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.
Pass such important information through context.Context
is not reliable.
If the call just pass a context.Background
, those information will loss.
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.
Any suggestion?
/run-all-tests |
LGTM. |
/run-all-tests |
/run-all-tests |
/run-unit-test |
/run-all-tests |
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.
LGTM
@@ -54,7 +60,7 @@ func RunInNewTxn(store Storage, retryable bool, f func(txn Transaction) error) e | |||
return errors.Trace(err) | |||
} | |||
|
|||
err = txn.Commit(context.Background()) | |||
err = txn.Commit(context.WithValue(context.Background(), Retryable, retryable)) |
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.
I really dislike passing those value through context, even txn.SetOption(retryable)
is better than this.
If you insist, I'll refactor the code here after it's merged.
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.
I've tried your suggestion and it's a little complex. I think to refactor the code in another PR is
ok for me.
store/tikv/latch/scheduler.go
Outdated
@@ -84,7 +84,7 @@ func (scheduler *LatchesScheduler) Lock(startTS uint64, keys [][]byte) *Lock { | |||
} | |||
|
|||
// UnLock unlocks a lock with commitTS. | |||
func (scheduler *LatchesScheduler) UnLock(lock *Lock, commitTS uint64) { | |||
func (scheduler *LatchesScheduler) UnLock(lock *Lock) { |
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.
IMHO, this API design is worse than before, because the user may forget to call lock.SetCommitTS
after UnLock, while previous API make a stronger contract.
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.
Both are ok for me. It's suggested by @coocood , maybe I could update it when you reach an agreement?
store/tikv/txn.go
Outdated
return nil | ||
|
||
defer func() { | ||
if err == nil { |
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.
I guess this can be moved into executeAndWriteFinishBinlog
, so defer
is unnecessary
/run-all-tests |
friendly ping @coocood |
LGTM |
@tiancaiamao @coocood @disksing PTAL