github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/milevadb-server/einsteindb/safepoint_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, 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 einsteindb
    15  
    16  import (
    17  	"context"
    18  	"fmt"
    19  	"time"
    20  
    21  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    22  	. "github.com/whtcorpsinc/check"
    23  	"github.com/whtcorpsinc/errors"
    24  	"github.com/whtcorpsinc/milevadb/ekv"
    25  )
    26  
    27  type testSafePointSuite struct {
    28  	OneByOneSuite
    29  	causetstore *einsteindbStore
    30  	prefix      string
    31  }
    32  
    33  var _ = Suite(&testSafePointSuite{})
    34  
    35  func (s *testSafePointSuite) SetUpSuite(c *C) {
    36  	s.OneByOneSuite.SetUpSuite(c)
    37  	s.causetstore = NewTestStore(c).(*einsteindbStore)
    38  	s.prefix = fmt.Sprintf("seek_%d", time.Now().Unix())
    39  }
    40  
    41  func (s *testSafePointSuite) TearDownSuite(c *C) {
    42  	err := s.causetstore.Close()
    43  	c.Assert(err, IsNil)
    44  	s.OneByOneSuite.TearDownSuite(c)
    45  }
    46  
    47  func (s *testSafePointSuite) beginTxn(c *C) *einsteindbTxn {
    48  	txn, err := s.causetstore.Begin()
    49  	c.Assert(err, IsNil)
    50  	return txn.(*einsteindbTxn)
    51  }
    52  
    53  func mymakeKeys(rowNum int, prefix string) []ekv.Key {
    54  	keys := make([]ekv.Key, 0, rowNum)
    55  	for i := 0; i < rowNum; i++ {
    56  		k := encodeKey(prefix, s08d("key", i))
    57  		keys = append(keys, k)
    58  	}
    59  	return keys
    60  }
    61  
    62  func (s *testSafePointSuite) waitUntilErrorPlugIn(t uint64) {
    63  	for {
    64  		saveSafePoint(s.causetstore.GetSafePointKV(), t+10)
    65  		cachedTime := time.Now()
    66  		newSafePoint, err := loadSafePoint(s.causetstore.GetSafePointKV())
    67  		if err == nil {
    68  			s.causetstore.UFIDelateSPCache(newSafePoint, cachedTime)
    69  			break
    70  		}
    71  		time.Sleep(time.Second)
    72  	}
    73  }
    74  
    75  func (s *testSafePointSuite) TestSafePoint(c *C) {
    76  	txn := s.beginTxn(c)
    77  	for i := 0; i < 10; i++ {
    78  		err := txn.Set(encodeKey(s.prefix, s08d("key", i)), valueBytes(i))
    79  		c.Assert(err, IsNil)
    80  	}
    81  	err := txn.Commit(context.Background())
    82  	c.Assert(err, IsNil)
    83  
    84  	// for txn get
    85  	txn2 := s.beginTxn(c)
    86  	_, err = txn2.Get(context.TODO(), encodeKey(s.prefix, s08d("key", 0)))
    87  	c.Assert(err, IsNil)
    88  
    89  	s.waitUntilErrorPlugIn(txn2.startTS)
    90  
    91  	_, geterr2 := txn2.Get(context.TODO(), encodeKey(s.prefix, s08d("key", 0)))
    92  	c.Assert(geterr2, NotNil)
    93  	isFallBehind := terror.ErrorEqual(errors.Cause(geterr2), ErrGCTooEarly)
    94  	isMayFallBehind := terror.ErrorEqual(errors.Cause(geterr2), ErrFIDelServerTimeout.GenWithStackByArgs("start timestamp may fall behind safe point"))
    95  	isBehind := isFallBehind || isMayFallBehind
    96  	c.Assert(isBehind, IsTrue)
    97  
    98  	// for txn seek
    99  	txn3 := s.beginTxn(c)
   100  
   101  	s.waitUntilErrorPlugIn(txn3.startTS)
   102  
   103  	_, seekerr := txn3.Iter(encodeKey(s.prefix, ""), nil)
   104  	c.Assert(seekerr, NotNil)
   105  	isFallBehind = terror.ErrorEqual(errors.Cause(geterr2), ErrGCTooEarly)
   106  	isMayFallBehind = terror.ErrorEqual(errors.Cause(geterr2), ErrFIDelServerTimeout.GenWithStackByArgs("start timestamp may fall behind safe point"))
   107  	isBehind = isFallBehind || isMayFallBehind
   108  	c.Assert(isBehind, IsTrue)
   109  
   110  	// for snapshot batchGet
   111  	keys := mymakeKeys(10, s.prefix)
   112  	txn4 := s.beginTxn(c)
   113  
   114  	s.waitUntilErrorPlugIn(txn4.startTS)
   115  
   116  	snapshot := newEinsteinDBSnapshot(s.causetstore, ekv.Version{Ver: txn4.StartTS()}, 0)
   117  	_, batchgeterr := snapshot.BatchGet(context.Background(), keys)
   118  	c.Assert(batchgeterr, NotNil)
   119  	isFallBehind = terror.ErrorEqual(errors.Cause(geterr2), ErrGCTooEarly)
   120  	isMayFallBehind = terror.ErrorEqual(errors.Cause(geterr2), ErrFIDelServerTimeout.GenWithStackByArgs("start timestamp may fall behind safe point"))
   121  	isBehind = isFallBehind || isMayFallBehind
   122  	c.Assert(isBehind, IsTrue)
   123  }