From c2e702afa2d744209d7696999eabbfc0e70f8645 Mon Sep 17 00:00:00 2001 From: wuxuelian Date: Mon, 13 Feb 2017 20:05:29 +0800 Subject: [PATCH 1/3] point_get:return latest committed version for get primary with start_ts==uint64::max(which means is a point get by pk or unique_key in tidb) --- src/storage/mvcc/reader.rs | 24 +++++++++++++++++------- tests/storage/test_storage.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/storage/mvcc/reader.rs b/src/storage/mvcc/reader.rs index 3f82fed487b..ab6bd8799d7 100644 --- a/src/storage/mvcc/reader.rs +++ b/src/storage/mvcc/reader.rs @@ -17,6 +17,7 @@ use super::{Error, Result}; use super::lock::Lock; use super::write::{Write, WriteType}; use raftstore::store::engine::{IterOption, SeekMode}; +use std::u64; #[derive(Clone, Default, Debug)] pub struct ScanMetrics { @@ -176,13 +177,22 @@ impl<'a> MvccReader<'a> { // Check for locks that signal concurrent writes. if let Some(lock) = try!(self.load_lock(key)) { if lock.ts <= ts { - // There is a pending lock. Client should wait or clean it. - return Err(Error::KeyIsLocked { - key: try!(key.raw()), - primary: lock.primary, - ts: lock.ts, - ttl: lock.ttl, - }); + let raw_key = try!(key.raw()); + let primary_key = lock.primary; + if ts == u64::MAX && raw_key == primary_key { + // when ts==MAX(which means it's a point get by pk or unique key), + // and current key is the primary key, + // return latest commit version's value + ts = lock.ts - 1; + } else { + // There is a pending lock. Client should wait or clean it. + return Err(Error::KeyIsLocked { + key: raw_key, + primary: primary_key, + ts: lock.ts, + ttl: lock.ttl, + }); + } } } loop { diff --git a/tests/storage/test_storage.rs b/tests/storage/test_storage.rs index 9cf20086c2e..03cfaf11e25 100644 --- a/tests/storage/test_storage.rs +++ b/tests/storage/test_storage.rs @@ -29,6 +29,7 @@ use super::util::new_raft_engine; use super::assert_storage::AssertionStorage; use storage::util; use std::collections::HashSet; +use std::u64; #[test] fn test_txn_store_get() { @@ -83,6 +84,31 @@ fn test_txn_store_cleanup_commit() { store.rollback_err(vec![b"primary"], 5); } +#[test] +fn test_txn_store_for_point_get_with_pk() { + let store = AssertionStorage::default(); + + store.put_ok(b"b", b"v2", 1, 2); + store.put_ok(b"primary", b"v1", 2, 3); + store.put_ok(b"secondary", b"v3", 3, 4); + store.prewrite_ok(vec![Mutation::Put((make_key(b"primary"), b"v3".to_vec())), + Mutation::Put((make_key(b"secondary"), b"s-5".to_vec())), + Mutation::Put((make_key(b"new_key"), b"new_key".to_vec()))], + b"primary", + 5); + store.get_ok(b"primary", 4, b"v1"); + store.get_ok(b"primary", u64::MAX, b"v1"); + store.get_err(b"primary", 6); + + store.get_ok(b"secondary", 4, b"v3"); + store.get_err(b"secondary", 6); + store.get_err(b"secondary", u64::MAX); + + store.get_err(b"new_key", 6); + store.get_ok(b"b", 6, b"v2"); + +} + #[test] fn test_txn_store_batch_get() { let store = AssertionStorage::default(); From 75edab819f0e8e478577a1b6896bd6e69c0342c3 Mon Sep 17 00:00:00 2001 From: wuxuelian Date: Thu, 16 Feb 2017 19:25:46 +0800 Subject: [PATCH 2/3] point_get:adjust code --- src/storage/mvcc/reader.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/storage/mvcc/reader.rs b/src/storage/mvcc/reader.rs index ab6bd8799d7..7047cd73199 100644 --- a/src/storage/mvcc/reader.rs +++ b/src/storage/mvcc/reader.rs @@ -177,18 +177,16 @@ impl<'a> MvccReader<'a> { // Check for locks that signal concurrent writes. if let Some(lock) = try!(self.load_lock(key)) { if lock.ts <= ts { - let raw_key = try!(key.raw()); - let primary_key = lock.primary; - if ts == u64::MAX && raw_key == primary_key { - // when ts==MAX(which means it's a point get by pk or unique key), + if ts == u64::MAX && try!(key.raw()) == lock.primary { + // when ts==MAX(which means get latest committed version for primary key), // and current key is the primary key, // return latest commit version's value ts = lock.ts - 1; } else { // There is a pending lock. Client should wait or clean it. return Err(Error::KeyIsLocked { - key: raw_key, - primary: primary_key, + key: try!(key.raw()), + primary: lock.primary, ts: lock.ts, ttl: lock.ttl, }); From a0e3fa0dac12f75d980931fd94b433c34c85af54 Mon Sep 17 00:00:00 2001 From: wuxuelian Date: Fri, 17 Feb 2017 11:13:29 +0800 Subject: [PATCH 3/3] point_get:adjust annotations --- src/storage/mvcc/reader.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/storage/mvcc/reader.rs b/src/storage/mvcc/reader.rs index 7047cd73199..dcab2681701 100644 --- a/src/storage/mvcc/reader.rs +++ b/src/storage/mvcc/reader.rs @@ -178,9 +178,9 @@ impl<'a> MvccReader<'a> { if let Some(lock) = try!(self.load_lock(key)) { if lock.ts <= ts { if ts == u64::MAX && try!(key.raw()) == lock.primary { - // when ts==MAX(which means get latest committed version for primary key), - // and current key is the primary key, - // return latest commit version's value + // when ts==u64::MAX(which means to get latest committed version for + // primary key),and current key is the primary key, returns the latest + // commit version's value ts = lock.ts - 1; } else { // There is a pending lock. Client should wait or clean it.