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  }