Skip to content

Commit

Permalink
*: fix the wrong check for key-need-lock of pessimistic transaction (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jackysp authored and ngaut committed Dec 15, 2019
1 parent 4410288 commit d666ed4
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
30 changes: 30 additions & 0 deletions session/pessimistic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -788,3 +788,33 @@ func (s *testPessimisticSuite) TestInnodbLockWaitTimeoutWaitStart(c *C) {
tk2.MustExec("rollback")
tk3.MustExec("commit")
}

func (s *testPessimisticSuite) TestPessimisticReadCommitted(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("use test")
tk1 := testkit.NewTestKitWithInit(c, s.store)
tk1.MustExec("use test")

tk.MustExec("set tidb_txn_mode = 'pessimistic'")
tk1.MustExec("set tidb_txn_mode = 'pessimistic'")

tk.MustExec("drop table if exists t;")
tk.MustExec("create table t(i int key);")
tk.MustExec("insert into t values (1);")
tk.MustQuery("select * from t").Check(testkit.Rows("1"))

tk.MustExec("begin;")
tk1.MustExec("begin;")
tk.MustExec("update t set i = -i;")

var wg sync.WaitGroup
wg.Add(1)
go func() {
tk1.MustExec("update t set i = -i;")
wg.Done()
}()
tk.MustExec("commit;")
wg.Wait()

tk1.MustExec("commit;")
}
2 changes: 1 addition & 1 deletion session/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ func keyNeedToLock(k, v []byte) bool {
if tablecodec.IsUntouchedIndexKValue(k, v) {
return false
}
isNonUniqueIndex := len(v) == 1
isNonUniqueIndex := tablecodec.IsIndexKey(k) && len(v) == 1
// Put row key and unique index need to lock.
return !isNonUniqueIndex
}
Expand Down
7 changes: 6 additions & 1 deletion tablecodec/tablecodec.go
Original file line number Diff line number Diff line change
Expand Up @@ -678,11 +678,16 @@ func GenTableIndexPrefix(tableID int64) kv.Key {
return appendTableIndexPrefix(buf, tableID)
}

// IsIndexKey is used to check whether the key is an index key.
func IsIndexKey(k []byte) bool {
return len(k) > 11 && k[0] == 't' && k[10] == 'i'
}

// IsUntouchedIndexKValue uses to check whether the key is index key, and the value is untouched,
// since the untouched index key/value is no need to commit.
func IsUntouchedIndexKValue(k, v []byte) bool {
vLen := len(v)
return (len(k) > 11 && k[0] == 't' && k[10] == 'i') &&
return IsIndexKey(k) &&
((vLen == 1 || vLen == 9) && v[vLen-1] == kv.UnCommitIndexKVFlag)
}

Expand Down

0 comments on commit d666ed4

Please sign in to comment.