Skip to content

Commit

Permalink
*: fix bug that write on temporary table send request to TiKV (#25535)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiancaiamao authored Jun 21, 2021
1 parent 7cafe81 commit 9f18723
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 38 deletions.
8 changes: 4 additions & 4 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8403,15 +8403,15 @@ func (s testSerialSuite) TestTemporaryTableNoNetwork(c *C) {
tk.MustExec("set tidb_enable_global_temporary_table=true")
tk.MustExec("create global temporary table tmp_t (id int, a int, index(a)) on commit delete rows")

tk.MustExec("begin")
tk.MustExec("insert into tmp_t values (1, 1)")
tk.MustExec("insert into tmp_t values (2, 2)")

c.Assert(failpoint.Enable("github.com/pingcap/tidb/store/mockstore/unistore/rpcServerBusy", "return(true)"), IsNil)
defer func() {
c.Assert(failpoint.Disable("github.com/pingcap/tidb/store/mockstore/unistore/rpcServerBusy"), IsNil)
}()

tk.MustExec("begin")
tk.MustExec("insert into tmp_t values (1, 1)")
tk.MustExec("insert into tmp_t values (2, 2)")

// Make sure the fail point works.
// With that failpoint, all requests to the TiKV is discard.
rs, err := tk1.Exec("select * from normal")
Expand Down
2 changes: 2 additions & 0 deletions kv/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ const (
MatchStoreLabels
// ResourceGroupTag indicates the resource group of the kv request.
ResourceGroupTag
// KVFilter indicates the filter to ignore key-values in the transaction's memory buffer.
KVFilter
)

// ReplicaReadType is the type of replica to read data from
Expand Down
48 changes: 14 additions & 34 deletions session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ import (
"github.com/pingcap/tidb/util/logutil"
"github.com/pingcap/tidb/util/sli"
"github.com/pingcap/tidb/util/sqlexec"
"github.com/pingcap/tidb/util/tableutil"
"github.com/pingcap/tidb/util/timeutil"
tikvstore "github.com/tikv/client-go/v2/kv"
"github.com/tikv/client-go/v2/tikv"
tikvutil "github.com/tikv/client-go/v2/util"
)
Expand Down Expand Up @@ -474,10 +476,6 @@ func (s *session) doCommit(ctx context.Context) error {
if err != nil {
return err
}
if err = s.removeTempTableFromBuffer(); err != nil {
return err
}

// mockCommitError and mockGetTSErrorInRetry use to test PR #8743.
failpoint.Inject("mockCommitError", func(val failpoint.Value) {
if val.(bool) && tikv.IsMockCommitErrorEnable() {
Expand Down Expand Up @@ -535,41 +533,23 @@ func (s *session) doCommit(ctx context.Context) error {
s.txn.SetOption(kv.GuaranteeLinearizability,
s.GetSessionVars().TxnCtx.IsExplicit && s.GetSessionVars().GuaranteeLinearizability)
}
if tables := s.GetSessionVars().TxnCtx.GlobalTemporaryTables; len(tables) > 0 {
s.txn.SetOption(kv.KVFilter, temporaryTableKVFilter(tables))
}

return s.txn.Commit(tikvutil.SetSessionID(ctx, s.GetSessionVars().ConnectionID))
}

// removeTempTableFromBuffer filters out the temporary table key-values.
func (s *session) removeTempTableFromBuffer() error {
tables := s.GetSessionVars().TxnCtx.GlobalTemporaryTables
if len(tables) == 0 {
return nil
}
memBuffer := s.txn.GetMemBuffer()
// Reset and new an empty stage buffer.
defer func() {
s.txn.cleanup()
}()
for tid := range tables {
seekKey := tablecodec.EncodeTablePrefix(tid)
endKey := tablecodec.EncodeTablePrefix(tid + 1)
iter, err := memBuffer.Iter(seekKey, endKey)
if err != nil {
return err
}
for iter.Valid() && iter.Key().HasPrefix(seekKey) {
if err = memBuffer.Delete(iter.Key()); err != nil {
return err
}
s.txn.UpdateEntriesCountAndSize()
if err = iter.Next(); err != nil {
return err
}
}
type temporaryTableKVFilter map[int64]tableutil.TempTable

func (m temporaryTableKVFilter) IsUnnecessaryKeyValue(key, value []byte, flags tikvstore.KeyFlags) bool {
tid := tablecodec.DecodeTableID(key)
if _, ok := m[tid]; ok {
return true
}
// Flush to the root membuffer.
s.txn.flushStmtBuf()
return nil

// This is the default filter for all tables.
return tablecodec.IsUntouchedIndexKValue(key, value)
}

// errIsNoisy is used to filter DUPLCATE KEY errors.
Expand Down
2 changes: 2 additions & 0 deletions store/driver/txn/txn_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ func (txn *tikvTxn) SetOption(opt int, val interface{}) {
txn.KVTxn.GetSnapshot().SetMatchStoreLabels(val.([]*metapb.StoreLabel))
case kv.ResourceGroupTag:
txn.KVTxn.SetResourceGroupTag(val.([]byte))
case kv.KVFilter:
txn.KVTxn.SetKVFilter(val.(tikv.KVFilter))
}
}

Expand Down

0 comments on commit 9f18723

Please sign in to comment.