github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/store/localstore/mvcc_test.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package localstore 15 16 import ( 17 "bytes" 18 "fmt" 19 "time" 20 21 . "github.com/insionng/yougam/libraries/pingcap/check" 22 "github.com/insionng/yougam/libraries/pingcap/tidb/kv" 23 "github.com/insionng/yougam/libraries/pingcap/tidb/store/localstore/goleveldb" 24 ) 25 26 var _ = Suite(&testMvccSuite{}) 27 28 type testMvccSuite struct { 29 s kv.Storage 30 } 31 32 func createMemStore(suffix int) kv.Storage { 33 // avoid cache 34 path := fmt.Sprintf("memory://%d", suffix) 35 d := Driver{ 36 goleveldb.MemoryDriver{}, 37 } 38 store, err := d.Open(path) 39 if err != nil { 40 panic(err) 41 } 42 return store 43 } 44 45 func (t *testMvccSuite) addDirtyData() { 46 engineDB := t.s.(*dbStore).db 47 b := engineDB.NewBatch() 48 b.Put([]byte("\xf0dirty"), []byte("testvalue")) 49 b.Put([]byte("\x00dirty"), []byte("testvalue")) 50 engineDB.Commit(b) 51 } 52 53 func (t *testMvccSuite) TestMvccEncode(c *C) { 54 encodedKey1 := MvccEncodeVersionKey([]byte("A"), kv.Version{Ver: 1}) 55 encodedKey2 := MvccEncodeVersionKey([]byte("A"), kv.Version{Ver: 2}) 56 // A_2 57 // A_1 58 c.Assert(encodedKey1.Cmp(encodedKey2), Greater, 0) 59 60 // decode test 61 key, ver, err := MvccDecode(encodedKey1) 62 c.Assert(err, IsNil) 63 c.Assert(bytes.Compare(key, []byte("A")), Equals, 0) 64 c.Assert(ver.Ver, Equals, uint64(1)) 65 } 66 67 func (t *testMvccSuite) scanRawEngine(c *C, f func([]byte, []byte)) { 68 // scan raw db 69 var k kv.Key 70 var v []byte 71 for { 72 var err error 73 k, v, err = t.s.(*dbStore).db.Seek(k) 74 if err != nil { 75 break 76 } 77 f(k, v) 78 k = k.Next() 79 } 80 } 81 82 func (t *testMvccSuite) SetUpTest(c *C) { 83 // create new store 84 t.s = createMemStore(time.Now().Nanosecond()) 85 t.addDirtyData() 86 // insert test data 87 txn, err := t.s.Begin() 88 c.Assert(err, IsNil) 89 for i := 0; i < 5; i++ { 90 val := encodeInt(i) 91 err := txn.Set(val, val) 92 c.Assert(err, IsNil) 93 } 94 txn.Commit() 95 } 96 97 func (t *testMvccSuite) TestMvccGet(c *C) { 98 txn, err := t.s.Begin() 99 c.Assert(err, IsNil) 100 k := encodeInt(1) 101 _, err = txn.Get(k) 102 c.Assert(err, IsNil) 103 // no such key 104 k = encodeInt(1024) 105 _, err = txn.Get(k) 106 c.Assert(err, NotNil) 107 txn.Commit() 108 } 109 110 func (t *testMvccSuite) TestMvccPutAndDel(c *C) { 111 txn, err := t.s.Begin() 112 c.Assert(err, IsNil) 113 // remove 0,1,2 114 for i := 0; i < 3; i++ { 115 val := encodeInt(i) 116 err = txn.Delete(val) 117 c.Assert(err, IsNil) 118 } 119 txn.Commit() 120 121 txn, _ = t.s.Begin() 122 _, err = txn.Get(encodeInt(0)) 123 c.Assert(err, NotNil) 124 v, err := txn.Get(encodeInt(4)) 125 c.Assert(err, IsNil) 126 c.Assert(len(v), Greater, 0) 127 txn.Commit() 128 129 cnt := 0 130 t.scanRawEngine(c, func(k, v []byte) { 131 cnt++ 132 }) 133 txn, _ = t.s.Begin() 134 txn.Set(encodeInt(0), []byte("v")) 135 _, err = txn.Get(encodeInt(0)) 136 c.Assert(err, IsNil) 137 txn.Commit() 138 139 cnt1 := 0 140 t.scanRawEngine(c, func(k, v []byte) { 141 cnt1++ 142 }) 143 c.Assert(cnt1, Greater, cnt) 144 } 145 146 func (t *testMvccSuite) TestMvccNext(c *C) { 147 txn, _ := t.s.Begin() 148 it, err := txn.Seek(encodeInt(2)) 149 c.Assert(err, IsNil) 150 c.Assert(it.Valid(), IsTrue) 151 for it.Valid() { 152 err = it.Next() 153 c.Assert(err, IsNil) 154 } 155 txn.Commit() 156 } 157 158 func encodeTestDataKey(i int) []byte { 159 return encodeInt(i) 160 } 161 162 func (t *testMvccSuite) TestSnapshotGet(c *C) { 163 tx, _ := t.s.Begin() 164 b, err := tx.Get(encodeInt(1)) 165 c.Assert(err, IsNil) 166 tx.Commit() 167 168 lastVer, err := globalVersionProvider.CurrentVersion() 169 c.Assert(err, IsNil) 170 // Modify 171 tx, _ = t.s.Begin() 172 err = tx.Set(encodeInt(1), []byte("new")) 173 c.Assert(err, IsNil) 174 err = tx.Commit() 175 c.Assert(err, IsNil) 176 testKey := encodeTestDataKey(1) 177 178 snapshot, err := t.s.GetSnapshot(kv.MaxVersion) 179 defer snapshot.Release() 180 b, err = snapshot.Get(testKey) 181 c.Assert(err, IsNil) 182 c.Assert(string(b), Equals, "new") 183 184 // Get last version 185 lastVerSnapshot, err := t.s.GetSnapshot(lastVer) 186 c.Assert(err, IsNil) 187 b, err = lastVerSnapshot.Get(testKey) 188 c.Assert(err, IsNil) 189 c.Assert(string(b), Equals, string(encodeInt(1))) 190 191 // Get version not exists 192 minVerSnapshot, err := t.s.GetSnapshot(kv.MinVersion) 193 c.Assert(err, IsNil) 194 _, err = minVerSnapshot.Get(testKey) 195 c.Assert(err, NotNil) 196 } 197 198 func (t *testMvccSuite) getSnapshot(c *C, ver kv.Version) *dbSnapshot { 199 snapshot, err := t.s.GetSnapshot(ver) 200 c.Assert(err, IsNil) 201 dbs, ok := snapshot.(*dbSnapshot) 202 c.Assert(ok, IsTrue) 203 return dbs 204 } 205 206 func (t *testMvccSuite) TestMvccSeek(c *C) { 207 s := t.getSnapshot(c, kv.MaxVersion) 208 k, v, err := s.mvccSeek(encodeInt(1), false) 209 c.Assert(err, IsNil) 210 c.Assert([]byte(k), BytesEquals, encodeInt(1)) 211 c.Assert(v, BytesEquals, encodeInt(1)) 212 213 k, v, err = s.mvccSeek(encodeInt(1024), false) 214 c.Assert(err, NotNil) 215 216 k, v, err = s.mvccSeek(append(encodeInt(1), byte(0)), false) 217 c.Assert(err, IsNil) 218 c.Assert([]byte(k), BytesEquals, encodeInt(2)) 219 220 k, v, err = s.mvccSeek(append(encodeInt(1), byte(0)), true) 221 c.Assert(err, NotNil) 222 223 s = t.getSnapshot(c, kv.Version{Ver: 1}) 224 k, v, err = s.mvccSeek(encodeInt(1), false) 225 c.Assert(err, NotNil) 226 227 txn, err := t.s.Begin() 228 c.Assert(err, IsNil) 229 err = txn.Set(encodeInt(3), encodeInt(1003)) 230 c.Assert(err, IsNil) 231 err = txn.Commit() 232 c.Assert(err, IsNil) 233 v1, err := globalVersionProvider.CurrentVersion() 234 c.Assert(err, IsNil) 235 236 txn, err = t.s.Begin() 237 c.Assert(err, IsNil) 238 err = txn.Delete(encodeInt(2)) 239 c.Assert(err, IsNil) 240 err = txn.Commit() 241 c.Assert(err, IsNil) 242 v2, err := globalVersionProvider.CurrentVersion() 243 c.Assert(err, IsNil) 244 245 s = t.getSnapshot(c, v2) 246 k, v, err = s.mvccSeek(encodeInt(2), false) 247 c.Assert(err, IsNil) 248 c.Assert([]byte(k), BytesEquals, encodeInt(3)) 249 c.Assert(v, BytesEquals, encodeInt(1003)) 250 251 s = t.getSnapshot(c, v1) 252 k, v, err = s.mvccSeek(encodeInt(2), false) 253 c.Assert(err, IsNil) 254 c.Assert([]byte(k), BytesEquals, encodeInt(2)) 255 c.Assert(v, BytesEquals, encodeInt(2)) 256 } 257 258 func (t *testMvccSuite) TestReverseMvccSeek(c *C) { 259 s := t.getSnapshot(c, kv.MaxVersion) 260 k, v, err := s.reverseMvccSeek(encodeInt(1024)) 261 c.Assert(err, IsNil) 262 c.Assert([]byte(k), BytesEquals, encodeInt(4)) 263 c.Assert(v, BytesEquals, encodeInt(4)) 264 265 k, v, err = s.reverseMvccSeek(encodeInt(0)) 266 c.Assert(err, NotNil) 267 268 k, v, err = s.reverseMvccSeek(append(encodeInt(1), byte(0))) 269 c.Assert(err, IsNil) 270 c.Assert([]byte(k), BytesEquals, encodeInt(1)) 271 272 s = t.getSnapshot(c, kv.Version{Ver: 1}) 273 k, v, err = s.reverseMvccSeek(encodeInt(1024)) 274 c.Assert(err, NotNil) 275 276 v0, err := globalVersionProvider.CurrentVersion() 277 c.Assert(err, IsNil) 278 279 txn, err := t.s.Begin() 280 c.Assert(err, IsNil) 281 err = txn.Set(encodeInt(3), encodeInt(1003)) 282 c.Assert(err, IsNil) 283 err = txn.Commit() 284 c.Assert(err, IsNil) 285 v1, err := globalVersionProvider.CurrentVersion() 286 c.Assert(err, IsNil) 287 288 txn, err = t.s.Begin() 289 c.Assert(err, IsNil) 290 err = txn.Delete(encodeInt(4)) 291 c.Assert(err, IsNil) 292 err = txn.Commit() 293 c.Assert(err, IsNil) 294 v2, err := globalVersionProvider.CurrentVersion() 295 c.Assert(err, IsNil) 296 297 s = t.getSnapshot(c, v2) 298 k, v, err = s.reverseMvccSeek(encodeInt(5)) 299 c.Assert(err, IsNil) 300 c.Assert([]byte(k), BytesEquals, encodeInt(3)) 301 c.Assert(v, BytesEquals, encodeInt(1003)) 302 303 s = t.getSnapshot(c, v1) 304 k, v, err = s.reverseMvccSeek(encodeInt(5)) 305 c.Assert(err, IsNil) 306 c.Assert([]byte(k), BytesEquals, encodeInt(4)) 307 c.Assert(v, BytesEquals, encodeInt(4)) 308 309 s = t.getSnapshot(c, v0) 310 k, v, err = s.reverseMvccSeek(encodeInt(4)) 311 c.Assert(err, IsNil) 312 c.Assert([]byte(k), BytesEquals, encodeInt(3)) 313 c.Assert(v, BytesEquals, encodeInt(3)) 314 } 315 316 func (t *testMvccSuite) TestMvccSuiteGetLatest(c *C) { 317 // update some new data 318 for i := 0; i < 10; i++ { 319 tx, _ := t.s.Begin() 320 err := tx.Set(encodeInt(5), encodeInt(100+i)) 321 c.Assert(err, IsNil) 322 err = tx.Commit() 323 c.Assert(err, IsNil) 324 } 325 // we can always read newest data 326 tx, _ := t.s.Begin() 327 b, err := tx.Get(encodeInt(5)) 328 c.Assert(err, IsNil) 329 c.Assert(string(b), Equals, string(encodeInt(100+9))) 330 // we can always scan newest data 331 it, err := tx.Seek(encodeInt(5)) 332 c.Assert(err, IsNil) 333 c.Assert(it.Valid(), IsTrue) 334 c.Assert(string(it.Value()), Equals, string(encodeInt(100+9))) 335 tx.Commit() 336 337 testKey := []byte("testKey") 338 txn0, _ := t.s.Begin() 339 txn0.Set(testKey, []byte("0")) 340 txn0.Commit() 341 txn1, _ := t.s.Begin() 342 { 343 // Commit another version 344 txn2, _ := t.s.Begin() 345 txn2.Set(testKey, []byte("2")) 346 txn2.Commit() 347 } 348 r, err := txn1.Get(testKey) 349 c.Assert(err, IsNil) 350 // Test isolation in transaction. 351 c.Assert(string(r), Equals, "0") 352 txn1.Commit() 353 } 354 355 func (t *testMvccSuite) TestBufferedIterator(c *C) { 356 s := createMemStore(time.Now().Nanosecond()) 357 tx, _ := s.Begin() 358 tx.Set([]byte{0x0, 0x0}, []byte("1")) 359 tx.Set([]byte{0x0, 0xff}, []byte("2")) 360 tx.Set([]byte{0x0, 0xee}, []byte("3")) 361 tx.Set([]byte{0x0, 0xee, 0xff}, []byte("4")) 362 tx.Set([]byte{0xff, 0xff, 0xee, 0xff}, []byte("5")) 363 tx.Set([]byte{0xff, 0xff, 0xff}, []byte("6")) 364 tx.Commit() 365 366 tx, _ = s.Begin() 367 iter, err := tx.Seek([]byte{0}) 368 c.Assert(err, IsNil) 369 cnt := 0 370 for iter.Valid() { 371 err = iter.Next() 372 c.Assert(err, IsNil) 373 cnt++ 374 } 375 tx.Commit() 376 c.Assert(cnt, Equals, 6) 377 378 tx, _ = s.Begin() 379 it, err := tx.Seek([]byte{0xff, 0xee}) 380 c.Assert(err, IsNil) 381 c.Assert(it.Valid(), IsTrue) 382 c.Assert(string(it.Key()), Equals, "\xff\xff\xee\xff") 383 tx.Commit() 384 385 // no such key 386 tx, _ = s.Begin() 387 it, err = tx.Seek([]byte{0xff, 0xff, 0xff, 0xff}) 388 c.Assert(err, IsNil) 389 c.Assert(it.Valid(), IsFalse) 390 391 it, err = tx.Seek([]byte{0x0, 0xff}) 392 c.Assert(err, IsNil) 393 c.Assert(it.Valid(), IsTrue) 394 c.Assert(it.Value(), DeepEquals, []byte("2")) 395 tx.Commit() 396 397 tx, _ = s.Begin() 398 iter, err = tx.SeekReverse(nil) 399 c.Assert(err, IsNil) 400 cnt = 0 401 for iter.Valid() { 402 err = iter.Next() 403 c.Assert(err, IsNil) 404 cnt++ 405 } 406 tx.Commit() 407 c.Assert(cnt, Equals, 6) 408 409 tx, _ = s.Begin() 410 it, err = tx.SeekReverse([]byte{0xff, 0xff, 0xff}) 411 c.Assert(err, IsNil) 412 c.Assert(it.Valid(), IsTrue) 413 c.Assert(string(it.Key()), Equals, "\xff\xff\xee\xff") 414 tx.Commit() 415 416 // no such key 417 tx, _ = s.Begin() 418 it, err = tx.SeekReverse([]byte{0x0, 0x0}) 419 c.Assert(err, IsNil) 420 c.Assert(it.Valid(), IsFalse) 421 422 it, err = tx.SeekReverse([]byte{0x0, 0xee}) 423 c.Assert(err, IsNil) 424 c.Assert(it.Valid(), IsTrue) 425 c.Assert(it.Value(), DeepEquals, []byte("1")) 426 tx.Commit() 427 } 428 429 func encodeInt(n int) []byte { 430 return []byte(fmt.Sprintf("%010d", n)) 431 } 432 433 func decodeInt(s []byte) int { 434 var n int 435 fmt.Sscanf(string(s), "%010d", &n) 436 return n 437 }