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

add newly inserted flag to optimize delete your write #378

Merged
merged 1 commit into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions integration_tests/2pc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1550,3 +1550,51 @@ func (s *testCommitterSuite) TestCommitMultipleRegions() {
}
s.mustCommit(m)
}

func (s *testCommitterSuite) TestNewlyInsertedMemDBFlag() {
ctx := context.Background()
txn := s.begin()
memdb := txn.GetMemBuffer()
k0 := []byte("k0")
v0 := []byte("v0")
k1 := []byte("k1")
k2 := []byte("k2")
v1 := []byte("v1")
v2 := []byte("v2")

// Insert after delete, the newly inserted flag should not exist.
err := txn.Delete(k0)
s.Nil(err)
err = txn.Set(k0, v0)
s.Nil(err)
flags, err := memdb.GetFlags(k0)
s.Nil(err)
s.False(flags.HasNewlyInserted())

// Lock then insert, the newly inserted flag should exist.
lockCtx := &kv.LockCtx{ForUpdateTS: txn.StartTS(), WaitStartTime: time.Now()}
err = txn.LockKeys(context.Background(), lockCtx, k1)
s.Nil(err)
err = txn.GetMemBuffer().SetWithFlags(k1, v1, kv.SetNewlyInserted)
s.Nil(err)
flags, err = memdb.GetFlags(k1)
s.Nil(err)
s.True(flags.HasNewlyInserted())

// Lock then delete and insert, the newly inserted flag should not exist.
err = txn.LockKeys(ctx, lockCtx, k2)
s.Nil(err)
err = txn.Delete(k2)
s.Nil(err)
flags, err = memdb.GetFlags(k2)
s.Nil(err)
s.False(flags.HasNewlyInserted())
err = txn.Set(k2, v2)
s.Nil(err)
flags, err = memdb.GetFlags(k2)
s.Nil(err)
s.False(flags.HasNewlyInserted())

err = txn.Commit(ctx)
s.Nil(err)
}
10 changes: 10 additions & 0 deletions kv/keyflags.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const (
flagPrewriteOnly
flagIgnoredIn2PC
flagReadable
flagNewlyInserted

persistentFlags = flagKeyLocked | flagKeyLockedValExist
)
Expand Down Expand Up @@ -98,6 +99,11 @@ func (f KeyFlags) AndPersistent() KeyFlags {
return f & persistentFlags
}

// HasNewlyInserted returns whether the in-transaction key is generated by an "insert" operation.
func (f KeyFlags) HasNewlyInserted() bool {
return f&flagNewlyInserted != 0
}

// ApplyFlagsOps applys flagspos to origin.
func ApplyFlagsOps(origin KeyFlags, ops ...FlagsOp) KeyFlags {
for _, op := range ops {
Expand Down Expand Up @@ -126,6 +132,8 @@ func ApplyFlagsOps(origin KeyFlags, ops ...FlagsOp) KeyFlags {
origin |= flagIgnoredIn2PC
case SetReadable:
origin |= flagReadable
case SetNewlyInserted:
origin |= flagNewlyInserted
}
}
return origin
Expand Down Expand Up @@ -160,4 +168,6 @@ const (
SetIgnoredIn2PC
// SetReadable marks the key is readable by in-transaction read.
SetReadable
// SetNewlyInserted marks the key is newly inserted with value length greater than zero.
SetNewlyInserted
)
19 changes: 15 additions & 4 deletions txnkv/transaction/2pc.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,21 @@ func (c *twoPhaseCommitter) initKeysAndMutations() error {
checkCnt++
memBuf.UpdateFlags(key, kv.SetPrewriteOnly)
} else {
// normal delete keys in optimistic txn can be delete without not exists checking
// delete-your-writes keys in pessimistic txn can ensure must be no exists so can directly delete them
op = kvrpcpb.Op_Del
delCnt++
if flags.HasNewlyInserted() {
// The delete-your-write keys in pessimistic transactions, only lock needed keys and skip
// other deletes for example the secondary index delete.
// Here if `tidb_constraint_check_in_place` is enabled and the transaction is in optimistic mode,
// the logic is same as the pessimistic mode.
if flags.HasLocked() {
op = kvrpcpb.Op_Lock
lockCnt++
} else {
continue
}
} else {
op = kvrpcpb.Op_Del
delCnt++
}
}
}
}
Expand Down