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

tikv: fix TxnSize to be the number of involved keys in the region #11725

Merged
merged 11 commits into from
Aug 19, 2019

Conversation

sticnarf
Copy link
Contributor

@sticnarf sticnarf commented Aug 13, 2019

What problem does this PR solve?

In prewrite, the TxnSize is now the number of keys in a single batch. Because there is a 16KB batch size limit, it is possible that we write a number of batches to the same region. Then, the TxnSize is actually not the number of keys involved in a single region.

What is changed and how it works?

I create a map in the twoPhaseCommitter to store the number of involved keys in each region. Then, we minimize the changes to the commit process. The map is used in buildPrewriteRequest to fill the TxnSize field in the PrewriteRequest.

Check List

Tests

  • Unit test

Code changes

  • Has exported function/method change
  • Has exported variable/fields change

Side effects

  • Possible performance regression
    • I think it is quite minor, though

Related changes

  • Need to update the documentation
    • I think we should clarify the meaning of TxnSize in kvproto

@CLAassistant
Copy link

CLAassistant commented Aug 13, 2019

CLA assistant check
All committers have signed the CLA.

@sticnarf sticnarf marked this pull request as ready for review August 13, 2019 06:55
@codecov
Copy link

codecov bot commented Aug 13, 2019

Codecov Report

Merging #11725 into master will not change coverage.
The diff coverage is n/a.

@@            Coverage Diff            @@
##            master    #11725   +/-   ##
=========================================
  Coverage   81.541%   81.541%           
=========================================
  Files          434       434           
  Lines        93857     93857           
=========================================
  Hits         76532     76532           
  Misses       11855     11855           
  Partials      5470      5470

@sticnarf
Copy link
Contributor Author

PTAL @disksing

@@ -323,6 +325,12 @@ func (c *twoPhaseCommitter) doActionOnKeys(bo *Backoffer, action twoPhaseCommitA
var batches []batchKeys
var sizeFunc = c.keySize
if action == actionPrewrite {
if c.regionTxnSize == nil {
c.regionTxnSize = make(map[RegionVerID]int)
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer to create it at initial phase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK. I will do it.

c.regionTxnSize = make(map[RegionVerID]int)
}
for region, keys := range groups {
c.regionTxnSize[region] = len(keys)
Copy link
Contributor

Choose a reason for hiding this comment

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

I noticed that the map is not recalculated when encounter region miss (may cause by region split or balance), during retry, all batch size will become 0.
A quick fix is to use region.ID as the map key instead, it's not 100% accurate but will be better.

Copy link
Contributor Author

@sticnarf sticnarf Aug 13, 2019

Choose a reason for hiding this comment

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

On region errors, now txn size will become the batch size instead of 0 because the failed batch will go through the whole prewrite process. Then, it will be as bad as the original code when we have large value size :(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There will be some other problems when we use region.ID as the map key. When there are several batches in a new region retrying concurrently, it is a problem how we update the txn size of the region...

Copy link
Contributor

Choose a reason for hiding this comment

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

oh good point 🤣

@sticnarf sticnarf force-pushed the correct-txn-size branch 2 times, most recently from adf8a49 to df8fb83 Compare August 13, 2019 12:12
@sticnarf
Copy link
Contributor Author

sticnarf commented Aug 13, 2019

Unexpected "resolve lock lite" is worse than doing more normal resolve lock. As we don't know what the transaction size when doing a retry, I propose we just set it to MaxUint64 to prevent resolve lock lite completely.
(Say we have a transaction who wrote hundreds of keys and died. The value size of each row is over 1KB. Then, the batch size is always under the threshold of doing a normal resolve lock. Now, a coprocessor request consistently encounters locks and only does resolve lock lite. It is disastrous because there can be tens of retries and the coprocessor progress is zeroed on each retry.)

@disksing PTAL again. Thanks!

@disksing
Copy link
Contributor

LGTM.
But both the lite resolve lock and preventing lite resolve lock seems more like a workaround rather than a solution...
Just a rough idea, maybe we can choose a strategy based on runtime statistics. For example, A) after retry a certain number of times, coprocessor scan and return all locks of the region, or B) tikv client uses resolve lock lite by default, if it encounters many locks for a same transaction, then it switches to the batch mode.

@sticnarf
Copy link
Contributor Author

sticnarf commented Aug 14, 2019

But both the lite resolve lock and preventing lite resolve lock seems more like a workaround rather than a solution...
Just a rough idea, maybe we can choose a strategy based on runtime statistics. For example, A) after retry a certain number of times, coprocessor scan and return all locks of the region, or B) tikv client uses resolve lock lite by default, if it encounters many locks for a same transaction, then it switches to the batch mode.

Yes, all of them are just workarounds. But I think the better solution is to make tikv able to resolve locks themselves (maybe embed a client in tikv) instead of trying reducing the resolve lock round trips between client and tikv. Then, there won't be abortion in cop processing and it is more controllable. For example, (just an inmature idea) tikv can maintain an LRU cache of unfinished locks, and resolve expired ones of them actively when the load is low.

@disksing
Copy link
Contributor

I guess this scheme violates our design philosophy, which is, tikv is not allowed to access tikv as a client...

@lysu lysu requested review from lysu and tiancaiamao August 15, 2019 06:06
Copy link
Contributor

@lysu lysu left a comment

Choose a reason for hiding this comment

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

LGTM

@lysu
Copy link
Contributor

lysu commented Aug 16, 2019

/run-all-tests

@lysu lysu added the type/bugfix This PR fixes a bug. label Aug 16, 2019
@sticnarf
Copy link
Contributor Author

/run-all-tests

@sticnarf
Copy link
Contributor Author

Can we merge it?

Copy link
Contributor

@lysu lysu left a comment

Choose a reason for hiding this comment

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

LGTM

@lysu
Copy link
Contributor

lysu commented Aug 19, 2019

@sticnarf do we need cherry-pick it to 3.0 ?

@lysu lysu added status/all tests passed status/LGT2 Indicates that a PR has LGTM 2. labels Aug 19, 2019
@tiancaiamao
Copy link
Contributor

LGTM

@tiancaiamao tiancaiamao added the status/can-merge Indicates a PR has been approved by a committer. label Aug 19, 2019
@sre-bot
Copy link
Contributor

sre-bot commented Aug 19, 2019

/run-all-tests

@sticnarf
Copy link
Contributor Author

@sticnarf do we need cherry-pick it to 3.0 ?

I'm inclined to. There is small chance (a transaction with many keys and big values is down and a coprocessor request needs to scan them) that inaccurate txn_size harms performance a lot.

@sre-bot sre-bot merged commit 5580a01 into pingcap:master Aug 19, 2019
@sre-bot
Copy link
Contributor

sre-bot commented Aug 19, 2019

cherry pick to release-3.0 failed

@sre-bot
Copy link
Contributor

sre-bot commented Apr 7, 2020

It seems that, not for sure, we failed to cherry-pick this commit to release-3.0. Please comment '/run-cherry-picker' to try to trigger the cherry-picker if we did fail to cherry-pick this commit before. @sticnarf PTAL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/tikv status/can-merge Indicates a PR has been approved by a committer. status/LGT2 Indicates that a PR has LGTM 2. type/bugfix This PR fixes a bug.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants