-
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
Changes from 2 commits
656dd7b
b51c483
ed8154b
41dc21c
2678449
25a893f
4a8e29b
cb90239
2502227
6f3263b
9b465c4
25faf0d
7657fa4
e8c279b
c6a0002
0c5caaa
37695a6
79fdafd
47d6420
f522381
1c0ab63
40da727
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,7 +112,22 @@ type contextKey string | |
// ConnID is the key in context. | ||
const ConnID contextKey = "conn ID" | ||
|
||
// SetConnID2Ctx sets the connection ID to context. | ||
func SetConnID2Ctx(ctx context.Context, sessCtx Context) context.Context { | ||
return context.WithValue(ctx, ConnID, sessCtx.GetSessionVars().ConnectionID) | ||
// Retryable is the key in context | ||
const Retryable contextKey = "Retryable" | ||
|
||
// SetCommitCtx sets the variables for context before commit a transaction. | ||
func SetCommitCtx(ctx context.Context, sessCtx Context) context.Context { | ||
ctx = context.WithValue(ctx, ConnID, sessCtx.GetSessionVars().ConnectionID) | ||
retryAble := !sessCtx.GetSessionVars().TxnCtx.ForUpdate | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. value of retryable. |
||
func GetRetryable(ctx context.Context) bool { | ||
var retryAble bool | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there is no need to capitalize the |
||
val := ctx.Value(Retryable) | ||
if val != nil { | ||
retryAble = val.(bool) | ||
} | ||
return retryAble | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -563,6 +563,17 @@ func (c *twoPhaseCommitter) cleanupKeys(bo *Backoffer, keys [][]byte) error { | |
// should be less than `gcRunInterval`. | ||
const maxTxnTimeUse = 590000 | ||
|
||
func (c *twoPhaseCommitter) executeAndWriteFinishBinlog(ctx context.Context) error { | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. redundant blank line. |
||
} else { | ||
c.writeFinishBinlog(binlog.BinlogType_Commit, int64(c.commitTS)) | ||
} | ||
return errors.Trace(err) | ||
} | ||
|
||
// execute executes the two-phase commit protocol. | ||
func (c *twoPhaseCommitter) execute(ctx context.Context) error { | ||
defer func() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ import ( | |
"github.com/pingcap/tidb/config" | ||
"github.com/pingcap/tidb/kv" | ||
"github.com/pingcap/tidb/metrics" | ||
"github.com/pingcap/tidb/store/tikv/latch" | ||
"github.com/pingcap/tidb/store/tikv/oracle" | ||
"github.com/pingcap/tidb/store/tikv/oracle/oracles" | ||
"github.com/pingcap/tidb/store/tikv/tikvrpc" | ||
|
@@ -71,6 +72,7 @@ func (d Driver) Open(path string) (kv.Storage, error) { | |
defer mc.Unlock() | ||
|
||
security := config.GetGlobalConfig().Security | ||
enableTxnLocalLatches := config.GetGlobalConfig().EnableTxnLocalLatches | ||
etcdAddrs, disableGC, err := parsePath(path) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
|
@@ -105,7 +107,7 @@ func (d Driver) Open(path string) (kv.Storage, error) { | |
return nil, errors.Trace(err) | ||
} | ||
|
||
s, err := newTikvStore(uuid, &codecPDClient{pdCli}, spkv, newRPCClient(security), !disableGC) | ||
s, err := newTikvStore(uuid, &codecPDClient{pdCli}, spkv, newRPCClient(security), !disableGC, enableTxnLocalLatches) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
} | ||
|
@@ -127,6 +129,7 @@ type tikvStore struct { | |
pdClient pd.Client | ||
regionCache *RegionCache | ||
lockResolver *LockResolver | ||
txnLatches *latch.LatchesScheduler | ||
gcWorker GCHandler | ||
etcdAddrs []string | ||
tlsConfig *tls.Config | ||
|
@@ -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 commentThe reason will be displayed to describe this comment to others. Learn more. There are too many arguments to new TiKVStore. |
||
o, err := oracles.NewPdOracle(pdClient, time.Duration(oracleUpdateInterval)*time.Millisecond) | ||
if err != nil { | ||
return nil, errors.Trace(err) | ||
|
@@ -183,6 +186,11 @@ func newTikvStore(uuid string, pdClient pd.Client, spkv SafePointKV, client Clie | |
closed: make(chan struct{}), | ||
} | ||
store.lockResolver = newLockResolver(store) | ||
if enableTxnLocalLatches { | ||
store.txnLatches = latch.NewScheduler(102400) | ||
} else { | ||
store.txnLatches = nil | ||
} | ||
store.enableGC = enableGC | ||
|
||
go store.runSafePointChecker() | ||
|
@@ -274,6 +282,10 @@ func (s *tikvStore) Close() error { | |
if err := s.client.Close(); err != nil { | ||
return errors.Trace(err) | ||
} | ||
|
||
if s.txnLatches != nil { | ||
s.txnLatches.Close() | ||
} | ||
return nil | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 commentThe reason will be displayed to describe this comment to others. Learn more. We can remove the argument, and set |
||
scheduler.RLock() | ||
defer scheduler.RUnlock() | ||
if !scheduler.closed { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,6 @@ import ( | |
"github.com/pingcap/tidb/kv" | ||
"github.com/pingcap/tidb/metrics" | ||
"github.com/pingcap/tidb/sessionctx" | ||
binlog "github.com/pingcap/tipb/go-binlog" | ||
log "github.com/sirupsen/logrus" | ||
"golang.org/x/net/context" | ||
) | ||
|
@@ -185,20 +184,44 @@ 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 commentThe reason will be displayed to describe this comment to others. Learn more. When will There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When no row needs to update in this transaction. |
||
return errors.Trace(err) | ||
} | ||
if committer == nil { | ||
return nil | ||
|
||
defer func() { | ||
if err == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this can be moved into |
||
txn.commitTS = committer.commitTS | ||
} | ||
}() | ||
// latches disabled | ||
if txn.store.txnLatches == nil { | ||
err = committer.executeAndWriteFinishBinlog(ctx) | ||
return errors.Trace(err) | ||
} | ||
err = committer.execute(ctx) | ||
if err != nil { | ||
committer.writeFinishBinlog(binlog.BinlogType_Rollback, 0) | ||
|
||
// latches enabled | ||
// 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 commentThe reason will be displayed to describe this comment to others. Learn more. Why use the |
||
return errors.Trace(err) | ||
} | ||
committer.writeFinishBinlog(binlog.BinlogType_Commit, int64(committer.commitTS)) | ||
txn.commitTS = committer.commitTS | ||
return nil | ||
|
||
// for transactions which need to acquire latches | ||
lock := txn.store.txnLatches.Lock(committer.startTS, committer.keys) | ||
defer func() { | ||
commitTS := uint64(0) | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we put |
||
}() | ||
if lock.IsStale() { | ||
err = errors.Errorf("startTS %d is stale", txn.startTS) | ||
return errors.Annotate(err, txnRetryableMark) | ||
} | ||
err = committer.executeAndWriteFinishBinlog(ctx) | ||
return errors.Trace(err) | ||
} | ||
|
||
func (txn *tikvTxn) close() { | ||
|
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?