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

txnkv: add new API for lock->put optimization #748

Merged
merged 3 commits into from
Mar 28, 2023

Conversation

zyguan
Copy link
Contributor

@zyguan zyguan commented Mar 28, 2023

This is a part of hotfix for pingcap/tidb#28011 . It allow us do lock->put optimization without touching membuf.

@@ -581,8 +606,8 @@ func (c *twoPhaseCommitter) initKeysAndMutations(ctx context.Context) error {
if c.txn.schemaAmender != nil || c.txn.assertionLevel == kvrpcpb.AssertionLevel_Off {
mustExist, mustNotExist, hasAssertUnknown = false, false, false
}
c.mutations.Push(op, isPessimistic, mustExist, mustNotExist, it.Handle())
size += len(key) + len(value)
c.mutations.Push(op, isPessimistic, mustExist, mustNotExist, it.Handle(), cachedValue)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments are left here, maybe avoiding using nil checking in the push function is safer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Push needs to take a parameter of type []byte as the lock->put value, since we do not overwrite membuf anymore (even on initKeysAndMutations).

if m.overlay == nil {
m.overlay = make(map[unionstore.MemKeyHandle][]byte)
}
m.overlay[handle] = value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could assert isPessimisticLock == true here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean panic on assertion failed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as it may prevent some data inconsistency risks.

Copy link
Contributor

@ekexium ekexium left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
We don't prevent others from mutating or reading that bypasses overlay. But I think it's OK considering this is just a hotfix.

mustLockKey := func(txn transaction.TxnProbe, key []byte) {
s.Require().NoError(txn.LockKeys(ctx, &kv.LockCtx{ForUpdateTS: txn.StartTS(), WaitStartTime: time.Now()}, key))
}
mutOpVals := func(opVals ...interface{}) func(m transaction.CommitterMutations) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just have a question: what does mut mean here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the abbr of 'mutation'. The function means to create a check function from mutation op-val pairs. I just want to make the name shorter, but yes, it's little hard to understand.

func(txn transaction.TxnProbe) { mustLockKey(txn, k1) },
func(txn transaction.TxnProbe) { s.Require().NoError(txn.Delete(k1)) },
},
mutOpVals(kvrpcpb.Op_Del, []byte{}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to test in different order, like calling txn.SetLockedKeyValue after calling LockKeys or any mutations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In tidb, SetLockedKeyValue is always called after LockKeys in point-get/batch-point-get (like the following). But I think it's ok to test it in arbitrary orders.

LockKeys(...)
for each unique keys {
  if uk not in membuf {
    SetLockedKeyValue(uk, val)
  }
}

@cfzjywxk cfzjywxk merged commit 603f10d into tikv:release-6.1-20230221-v6.1.1-hotfix Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants