github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/milevadb-server/2pc_fail_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  
    19  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    20  	. "github.com/whtcorpsinc/check"
    21  	"github.com/whtcorpsinc/errors"
    22  	"github.com/whtcorpsinc/failpoint"
    23  	"github.com/whtcorpsinc/milevadb/ekv"
    24  	"github.com/whtcorpsinc/milevadb/soliton/israce"
    25  )
    26  
    27  // TestFailCommitPrimaryRpcErrors tests rpc errors are handled properly when
    28  // committing primary region task.
    29  func (s *testCommitterSuite) TestFailCommitPrimaryRpcErrors(c *C) {
    30  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitResult", `return("timeout")`), IsNil)
    31  	defer func() {
    32  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitResult"), IsNil)
    33  	}()
    34  	// The rpc error will be wrapped to ErrResultUndetermined.
    35  	t1 := s.begin(c)
    36  	err := t1.Set([]byte("a"), []byte("a1"))
    37  	c.Assert(err, IsNil)
    38  	err = t1.Commit(context.Background())
    39  	c.Assert(err, NotNil)
    40  	c.Assert(terror.ErrorEqual(err, terror.ErrResultUndetermined), IsTrue, Commentf("%s", errors.ErrorStack(err)))
    41  
    42  	// We don't need to call "Rollback" after "Commit" fails.
    43  	err = t1.Rollback()
    44  	c.Assert(err, Equals, ekv.ErrInvalidTxn)
    45  }
    46  
    47  // TestFailCommitPrimaryRegionError tests RegionError is handled properly when
    48  // committing primary region task.
    49  func (s *testCommitterSuite) TestFailCommitPrimaryRegionError(c *C) {
    50  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitResult", `return("notLeader")`), IsNil)
    51  	defer func() {
    52  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitResult"), IsNil)
    53  	}()
    54  	// Ensure it returns the original error without wrapped to ErrResultUndetermined
    55  	// if it exceeds max retry timeout on RegionError.
    56  	t2 := s.begin(c)
    57  	err := t2.Set([]byte("b"), []byte("b1"))
    58  	c.Assert(err, IsNil)
    59  	err = t2.Commit(context.Background())
    60  	c.Assert(err, NotNil)
    61  	c.Assert(terror.ErrorNotEqual(err, terror.ErrResultUndetermined), IsTrue)
    62  }
    63  
    64  // TestFailCommitPrimaryRPCErrorThenRegionError tests the case when commit first
    65  // receive a rpc timeout, then region errors afterwrards.
    66  func (s *testCommitterSuite) TestFailCommitPrimaryRPCErrorThenRegionError(c *C) {
    67  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitResult", `1*return("timeout")->return("notLeader")`), IsNil)
    68  	defer func() {
    69  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitResult"), IsNil)
    70  	}()
    71  	// The region error will be wrapped to ErrResultUndetermined.
    72  	t1 := s.begin(c)
    73  	err := t1.Set([]byte("a"), []byte("a1"))
    74  	c.Assert(err, IsNil)
    75  	err = t1.Commit(context.Background())
    76  	c.Assert(err, NotNil)
    77  	c.Assert(terror.ErrorEqual(err, terror.ErrResultUndetermined), IsTrue, Commentf("%s", errors.ErrorStack(err)))
    78  }
    79  
    80  // TestFailCommitPrimaryKeyError tests KeyError is handled properly when
    81  // committing primary region task.
    82  func (s *testCommitterSuite) TestFailCommitPrimaryKeyError(c *C) {
    83  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitResult", `return("keyError")`), IsNil)
    84  	defer func() {
    85  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitResult"), IsNil)
    86  	}()
    87  	// Ensure it returns the original error without wrapped to ErrResultUndetermined
    88  	// if it meets KeyError.
    89  	t3 := s.begin(c)
    90  	err := t3.Set([]byte("c"), []byte("c1"))
    91  	c.Assert(err, IsNil)
    92  	err = t3.Commit(context.Background())
    93  	c.Assert(err, NotNil)
    94  	c.Assert(terror.ErrorNotEqual(err, terror.ErrResultUndetermined), IsTrue)
    95  }
    96  
    97  func (s *testCommitterSuite) TestFailCommitTimeout(c *C) {
    98  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitTimeout", `return(true)`), IsNil)
    99  	defer func() {
   100  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcCommitTimeout"), IsNil)
   101  	}()
   102  	txn := s.begin(c)
   103  	err := txn.Set([]byte("a"), []byte("a1"))
   104  	c.Assert(err, IsNil)
   105  	err = txn.Set([]byte("b"), []byte("b1"))
   106  	c.Assert(err, IsNil)
   107  	err = txn.Set([]byte("c"), []byte("c1"))
   108  	c.Assert(err, IsNil)
   109  	err = txn.Commit(context.Background())
   110  	c.Assert(err, NotNil)
   111  
   112  	txn2 := s.begin(c)
   113  	value, err := txn2.Get(context.TODO(), []byte("a"))
   114  	c.Assert(err, IsNil)
   115  	c.Assert(len(value), Greater, 0)
   116  	_, err = txn2.Get(context.TODO(), []byte("b"))
   117  	c.Assert(err, IsNil)
   118  	c.Assert(len(value), Greater, 0)
   119  }
   120  
   121  // TestFailPrewriteRegionError tests data race does not happen on retries
   122  func (s *testCommitterSuite) TestFailPrewriteRegionError(c *C) {
   123  	if israce.RaceEnabled {
   124  		c.Skip("skip race test")
   125  	}
   126  	c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcPrewriteResult", `return("notLeader")`), IsNil)
   127  	defer func() {
   128  		c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/causetstore/mockstore/mockeinsteindb/rpcPrewriteResult"), IsNil)
   129  	}()
   130  
   131  	txn := s.begin(c)
   132  
   133  	// Set the value big enough to create many batches. This increases the chance of data races.
   134  	var bigVal [18000]byte
   135  	for i := 0; i < 1000; i++ {
   136  		err := txn.Set([]byte{byte(i)}, bigVal[:])
   137  		c.Assert(err, IsNil)
   138  	}
   139  
   140  	committer, err := newTwoPhaseCommitterWithInit(txn, 1)
   141  	c.Assert(err, IsNil)
   142  
   143  	ctx := context.Background()
   144  	err = committer.prewriteMutations(NewBackofferWithVars(ctx, 1000, nil), committer.mutations)
   145  	c.Assert(err, NotNil)
   146  }