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/resolvelock: resolve lock in a batch #2389
Merged
Merged
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
30ac913
scheduler: batch resolve lock.
atmzhou caf1747
Merge branch 'master' into ningnanzhou/batchlockresolve
atmzhou 419473e
clean code
atmzhou 881d593
clean code
atmzhou bd2fec4
clean code
atmzhou c9efcc4
clean code
atmzhou 07ec429
Merge branch 'master' into ningnanzhou/batchlockresolve
atmzhou c0882f6
Merge branch 'master' into ningnanzhou/batchlockresolve
atmzhou b53b1a0
add test
atmzhou 1ed7a1e
clean code
atmzhou 2aac8d5
git pull
atmzhou c06d81c
address comments.
disksing 5ef4d87
address comments.
disksing f03b228
address comments.
disksing 8489f7d
Merge branch 'master' into ningnanzhou/batchlockresolve
disksing 1cc7613
address comment.
disksing 2ac4bac
address comment.
disksing cc277c0
Merge branch 'master' into ningnanzhou/batchlockresolve
disksing 68d5eb8
address comment.
disksing 3beee32
Merge branch 'master' into ningnanzhou/batchlockresolve
disksing e90824a
Merge branch 'master' into ningnanzhou/batchlockresolve
disksing 97cfda7
Merge branch 'master' into ningnanzhou/batchlockresolve
siddontang File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ use std::time::Duration; | |
use std::thread; | ||
use std::hash::{Hash, Hasher}; | ||
use std::u64; | ||
use std::mem; | ||
|
||
use prometheus::HistogramTimer; | ||
use kvproto::kvrpcpb::{CommandPri, Context, LockInfo}; | ||
|
@@ -63,7 +64,9 @@ use super::super::metrics::*; | |
// TODO: make it configurable. | ||
pub const GC_BATCH_SIZE: usize = 512; | ||
|
||
pub const RESOLVE_LOCK_BATCH_SIZE: usize = 512; | ||
// To resolve a key, the write size is about 100~150 bytes, depending on key and value length. | ||
// The write batch will be around 32KB if we scan 256 keys each time. | ||
pub const RESOLVE_LOCK_BATCH_SIZE: usize = 256; | ||
|
||
/// Process result of a command. | ||
pub enum ProcessResult { | ||
|
@@ -585,12 +588,9 @@ fn process_read( | |
Err(e) => ProcessResult::Failed { err: e.into() }, | ||
} | ||
} | ||
// Scan the locks with timestamp `start_ts`, then either commit them if the command has | ||
// commit timestamp populated or rollback otherwise. | ||
Command::ResolveLock { | ||
ref ctx, | ||
start_ts, | ||
commit_ts, | ||
ref mut txn_status, | ||
ref mut scan_key, | ||
.. | ||
} => { | ||
|
@@ -605,24 +605,23 @@ fn process_read( | |
let res = reader | ||
.scan_lock( | ||
scan_key.take(), | ||
|lock| lock.ts == start_ts, | ||
|lock| txn_status.contains_key(&lock.ts), | ||
Some(RESOLVE_LOCK_BATCH_SIZE), | ||
) | ||
.map_err(Error::from) | ||
.and_then(|(v, next_scan_key)| { | ||
let keys: Vec<Key> = v.into_iter().map(|x| x.0).collect(); | ||
let key_locks: Vec<_> = v.into_iter().map(|x| x).collect(); | ||
KV_COMMAND_KEYREAD_HISTOGRAM_VEC | ||
.with_label_values(&[tag]) | ||
.observe(keys.len() as f64); | ||
if keys.is_empty() { | ||
.observe(key_locks.len() as f64); | ||
if key_locks.is_empty() { | ||
Ok(None) | ||
} else { | ||
Ok(Some(Command::ResolveLock { | ||
ctx: ctx.clone(), | ||
start_ts: start_ts, | ||
commit_ts: commit_ts, | ||
txn_status: mem::replace(txn_status, Default::default()), | ||
scan_key: next_scan_key, | ||
keys: keys, | ||
key_locks: key_locks, | ||
})) | ||
} | ||
}); | ||
|
@@ -884,52 +883,58 @@ fn process_write_impl( | |
} | ||
Command::ResolveLock { | ||
ref ctx, | ||
start_ts, | ||
commit_ts, | ||
ref mut txn_status, | ||
ref mut scan_key, | ||
ref keys, | ||
ref key_locks, | ||
} => { | ||
if let Some(cts) = commit_ts { | ||
if cts <= start_ts { | ||
return Err(Error::InvalidTxnTso { | ||
start_ts: start_ts, | ||
commit_ts: cts, | ||
}); | ||
} | ||
} | ||
let mut scan_key = scan_key.take(); | ||
let mut txn = MvccTxn::new( | ||
snapshot, | ||
statistics, | ||
start_ts, | ||
None, | ||
ctx.get_isolation_level(), | ||
!ctx.get_not_fill_cache(), | ||
); | ||
let rows = keys.len(); | ||
for k in keys { | ||
match commit_ts { | ||
Some(ts) => txn.commit(k, ts)?, | ||
None => txn.rollback(k)?, | ||
let mut modifies: Vec<Modify> = vec![]; | ||
let mut write_size = 0; | ||
let rows = key_locks.len(); | ||
for &(ref current_key, ref current_lock) in key_locks { | ||
let mut txn = MvccTxn::new( | ||
snapshot, | ||
statistics, | ||
current_lock.ts, | ||
None, | ||
ctx.get_isolation_level(), | ||
!ctx.get_not_fill_cache(), | ||
); | ||
let status = txn_status.get(¤t_lock.ts); | ||
let commit_ts = match status { | ||
Some(ts) => *ts, | ||
None => panic!("txn status not found."), | ||
}; | ||
if commit_ts > 0 { | ||
if current_lock.ts >= commit_ts { | ||
return Err(Error::InvalidTxnTso { | ||
start_ts: current_lock.ts, | ||
commit_ts: commit_ts, | ||
}); | ||
} | ||
txn.commit(current_key, commit_ts)?; | ||
} else { | ||
txn.rollback(current_key)?; | ||
} | ||
if txn.write_size() >= MAX_TXN_WRITE_SIZE { | ||
scan_key = Some(k.to_owned()); | ||
write_size += txn.write_size(); | ||
modifies.append(&mut txn.modifies()); | ||
if write_size >= MAX_TXN_WRITE_SIZE { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please adjust |
||
scan_key = Some(current_key.to_owned()); | ||
break; | ||
} | ||
} | ||
if scan_key.is_none() { | ||
(ProcessResult::Res, txn.modifies(), rows) | ||
(ProcessResult::Res, modifies, rows) | ||
} else { | ||
let pr = ProcessResult::NextCommand { | ||
cmd: Command::ResolveLock { | ||
ctx: ctx.clone(), | ||
start_ts: start_ts, | ||
commit_ts: commit_ts, | ||
txn_status: mem::replace(txn_status, Default::default()), | ||
scan_key: scan_key.take(), | ||
keys: vec![], | ||
key_locks: vec![], | ||
}, | ||
}; | ||
(pr, txn.modifies(), rows) | ||
(pr, modifies, rows) | ||
} | ||
} | ||
Command::Gc { | ||
|
@@ -1535,9 +1540,13 @@ pub fn gen_command_lock(latches: &Latches, cmd: &Command) -> Lock { | |
let keys: Vec<&Key> = mutations.iter().map(|x| x.key()).collect(); | ||
latches.gen_lock(&keys) | ||
} | ||
Command::Commit { ref keys, .. } | | ||
Command::Rollback { ref keys, .. } | | ||
Command::ResolveLock { ref keys, .. } => latches.gen_lock(keys), | ||
Command::ResolveLock { ref key_locks, .. } => { | ||
let keys: Vec<&Key> = key_locks.iter().map(|x| &x.0).collect(); | ||
latches.gen_lock(&keys) | ||
} | ||
Command::Commit { ref keys, .. } | Command::Rollback { ref keys, .. } => { | ||
latches.gen_lock(keys) | ||
} | ||
Command::Cleanup { ref key, .. } => latches.gen_lock(&[key]), | ||
_ => Lock::new(vec![]), | ||
} | ||
|
@@ -1547,11 +1556,15 @@ pub fn gen_command_lock(latches: &Latches, cmd: &Command) -> Lock { | |
mod tests { | ||
use super::*; | ||
use kvproto::kvrpcpb::Context; | ||
use util::collections::HashMap; | ||
use storage::txn::latch::*; | ||
use storage::{make_key, Command, Mutation, Options}; | ||
use storage::mvcc; | ||
|
||
#[test] | ||
fn test_command_latches() { | ||
let mut temp_map = HashMap::default(); | ||
temp_map.insert(10, 20); | ||
let readonly_cmds = vec![ | ||
Command::Get { | ||
ctx: Context::new(), | ||
|
@@ -1576,10 +1589,9 @@ mod tests { | |
}, | ||
Command::ResolveLock { | ||
ctx: Context::new(), | ||
start_ts: 10, | ||
commit_ts: Some(20), | ||
txn_status: temp_map.clone(), | ||
scan_key: None, | ||
keys: vec![], | ||
key_locks: vec![], | ||
}, | ||
Command::Gc { | ||
ctx: Context::new(), | ||
|
@@ -1623,10 +1635,14 @@ mod tests { | |
}, | ||
Command::ResolveLock { | ||
ctx: Context::new(), | ||
start_ts: 10, | ||
commit_ts: Some(20), | ||
txn_status: temp_map.clone(), | ||
scan_key: None, | ||
keys: vec![make_key(b"k")], | ||
key_locks: vec![ | ||
( | ||
make_key(b"k"), | ||
mvcc::Lock::new(mvcc::LockType::Put, b"k".to_vec(), 10, 20, None), | ||
), | ||
], | ||
}, | ||
]; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with capacity