github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/cmd/benchdb/ddltest/ddl_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 dbstest
    15  
    16  import (
    17  	"database/allegrosql"
    18  	"database/allegrosql/driver"
    19  	"flag"
    20  	"fmt"
    21  	"math/rand"
    22  	"os"
    23  	"os/exec"
    24  	"reflect"
    25  	"runtime"
    26  	"strings"
    27  	"sync"
    28  	"sync/atomic"
    29  	"testing"
    30  	"time"
    31  
    32  	_ "github.com/go-allegrosql-driver/allegrosql"
    33  	log "github.com/sirupsen/logrus"
    34  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    35  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    36  	. "github.com/whtcorpsinc/check"
    37  	"github.com/whtcorpsinc/errors"
    38  	zaplog "github.com/whtcorpsinc/log"
    39  	"github.com/whtcorpsinc/milevadb/causet"
    40  	"github.com/whtcorpsinc/milevadb/causetstore"
    41  	"github.com/whtcorpsinc/milevadb/causetstore/einsteindb"
    42  	"github.com/whtcorpsinc/milevadb/dbs"
    43  	"github.com/whtcorpsinc/milevadb/ekv"
    44  	"github.com/whtcorpsinc/milevadb/petri"
    45  	"github.com/whtcorpsinc/milevadb/soliton/logutil"
    46  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    47  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    48  	"github.com/whtcorpsinc/milevadb/stochastik"
    49  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    50  	"github.com/whtcorpsinc/milevadb/types"
    51  	goctx "golang.org/x/net/context"
    52  )
    53  
    54  func TestDBS(t *testing.T) {
    55  	CustomVerboseFlag = true
    56  	TestingT(t)
    57  }
    58  
    59  var (
    60  	etcd              = flag.String("etcd", "127.0.0.1:2379", "etcd path")
    61  	milevadbIP        = flag.String("milevadb_ip", "127.0.0.1", "milevadb-server ip address")
    62  	einsteindbPath    = flag.String("einsteindb_path", "", "einsteindb path")
    63  	lease             = flag.Int("lease", 1, "DBS schemaReplicant lease time, seconds")
    64  	serverNum         = flag.Int("server_num", 3, "Maximum running milevadb server")
    65  	startPort         = flag.Int("start_port", 5000, "First milevadb-server listening port")
    66  	statusPort        = flag.Int("status_port", 8000, "First milevadb-server status port")
    67  	logLevel          = flag.String("L", "error", "log level")
    68  	dbsServerLogLevel = flag.String("dbs_log_level", "fatal", "DBS server log level")
    69  	dataNum           = flag.Int("n", 100, "minimal test dataset for a causet")
    70  	enableRestart     = flag.Bool("enable_restart", true, "whether random restart servers for tests")
    71  )
    72  
    73  var _ = Suite(&TestDBSSuite{})
    74  
    75  type server struct {
    76  	*exec.Cmd
    77  	logFP *os.File
    78  	EDB   *allegrosql.EDB
    79  	addr  string
    80  }
    81  
    82  type TestDBSSuite struct {
    83  	causetstore ekv.CausetStorage
    84  	dom         *petri.Petri
    85  	s           stochastik.Stochastik
    86  	ctx         stochastikctx.Context
    87  
    88  	m     sync.Mutex
    89  	procs []*server
    90  
    91  	wg   sync.WaitGroup
    92  	quit chan struct{}
    93  
    94  	retryCount int
    95  
    96  	solitonutil.CommonHandleSuite
    97  }
    98  
    99  func (s *TestDBSSuite) SetUpSuite(c *C) {
   100  	logutil.InitLogger(&logutil.LogConfig{Config: zaplog.Config{Level: *logLevel}})
   101  
   102  	s.quit = make(chan struct{})
   103  
   104  	var err error
   105  	s.causetstore, err = causetstore.New(fmt.Sprintf("einsteindb://%s%s", *etcd, *einsteindbPath))
   106  	c.Assert(err, IsNil)
   107  
   108  	// Make sure the schemaReplicant lease of this stochastik is equal to other MilevaDB servers'.
   109  	stochastik.SetSchemaLease(time.Duration(*lease) * time.Second)
   110  
   111  	s.dom, err = stochastik.BootstrapStochastik(s.causetstore)
   112  	c.Assert(err, IsNil)
   113  
   114  	s.s, err = stochastik.CreateStochastik(s.causetstore)
   115  	c.Assert(err, IsNil)
   116  
   117  	s.ctx = s.s.(stochastikctx.Context)
   118  	goCtx := goctx.Background()
   119  	_, err = s.s.InterDircute(goCtx, "create database if not exists test_dbs")
   120  	c.Assert(err, IsNil)
   121  
   122  	s.Bootstrap(c)
   123  
   124  	// Stop current DBS worker, so that we can't be the tenant now.
   125  	err = petri.GetPetri(s.ctx).DBS().Stop()
   126  	c.Assert(err, IsNil)
   127  	dbs.RunWorker = false
   128  	stochastik.ResetStoreForWithEinsteinDBTest(s.causetstore)
   129  	s.s, err = stochastik.CreateStochastik(s.causetstore)
   130  	c.Assert(err, IsNil)
   131  	s.dom, err = stochastik.BootstrapStochastik(s.causetstore)
   132  	c.Assert(err, IsNil)
   133  	s.ctx = s.s.(stochastikctx.Context)
   134  	_, err = s.s.InterDircute(goCtx, "use test_dbs")
   135  	c.Assert(err, IsNil)
   136  
   137  	addEnvPath("..")
   138  
   139  	// Start multi milevadb servers
   140  	s.procs = make([]*server, *serverNum)
   141  
   142  	// Set server restart retry count.
   143  	s.retryCount = 5
   144  
   145  	createLogFiles(c, *serverNum)
   146  	err = s.startServers()
   147  	c.Assert(err, IsNil)
   148  
   149  	s.wg.Add(1)
   150  	go s.restartServerRegularly()
   151  }
   152  
   153  // restartServerRegularly restarts a milevadb server regularly.
   154  func (s *TestDBSSuite) restartServerRegularly() {
   155  	defer s.wg.Done()
   156  
   157  	var err error
   158  	after := *lease * (6 + randomIntn(6))
   159  	for {
   160  		select {
   161  		case <-time.After(time.Duration(after) * time.Second):
   162  			if *enableRestart {
   163  				err = s.restartServerRand()
   164  				if err != nil {
   165  					log.Fatalf("restartServerRand failed, err %v", errors.ErrorStack(err))
   166  				}
   167  			}
   168  		case <-s.quit:
   169  			return
   170  		}
   171  	}
   172  }
   173  
   174  func (s *TestDBSSuite) TearDownSuite(c *C) {
   175  	close(s.quit)
   176  	s.wg.Wait()
   177  
   178  	s.dom.Close()
   179  	// TODO: Remove these logs after testing.
   180  	quitCh := make(chan struct{})
   181  	go func() {
   182  		select {
   183  		case <-time.After(100 * time.Second):
   184  			buf := make([]byte, 2<<20)
   185  			size := runtime.Stack(buf, true)
   186  			log.Errorf("%s", buf[:size])
   187  		case <-quitCh:
   188  		}
   189  	}()
   190  	err := s.causetstore.Close()
   191  	c.Assert(err, IsNil)
   192  	close(quitCh)
   193  
   194  	err = s.stopServers()
   195  	c.Assert(err, IsNil)
   196  }
   197  
   198  func (s *TestDBSSuite) startServers() (err error) {
   199  	s.m.Lock()
   200  	defer s.m.Unlock()
   201  
   202  	for i := 0; i < len(s.procs); i++ {
   203  		if s.procs[i] != nil {
   204  			continue
   205  		}
   206  
   207  		// Open log file.
   208  		logFP, err := os.OpenFile(fmt.Sprintf("%s%d", logFilePrefix, i), os.O_RDWR, 0766)
   209  		if err != nil {
   210  			return errors.Trace(err)
   211  		}
   212  
   213  		s.procs[i], err = s.startServer(i, logFP)
   214  		if err != nil {
   215  			return errors.Trace(err)
   216  		}
   217  	}
   218  
   219  	return nil
   220  }
   221  
   222  func (s *TestDBSSuite) killServer(proc *os.Process) error {
   223  	// Make sure this milevadb is killed, and it makes the next milevadb that has the same port as this one start quickly.
   224  	err := proc.Kill()
   225  	if err != nil {
   226  		log.Errorf("kill server failed err %v", err)
   227  		return errors.Trace(err)
   228  	}
   229  	_, err = proc.Wait()
   230  	if err != nil {
   231  		log.Errorf("kill server, wait failed err %v", err)
   232  		return errors.Trace(err)
   233  	}
   234  
   235  	time.Sleep(1 * time.Second)
   236  	return nil
   237  }
   238  
   239  func (s *TestDBSSuite) stopServers() error {
   240  	s.m.Lock()
   241  	defer s.m.Unlock()
   242  
   243  	for i := 0; i < len(s.procs); i++ {
   244  		if s.procs[i] != nil {
   245  			err := s.killServer(s.procs[i].Process)
   246  			if err != nil {
   247  				return errors.Trace(err)
   248  			}
   249  			s.procs[i] = nil
   250  		}
   251  	}
   252  	return nil
   253  }
   254  
   255  var logFilePrefix = "milevadb_log_file_"
   256  
   257  func createLogFiles(c *C, length int) {
   258  	for i := 0; i < length; i++ {
   259  		fp, err := os.Create(fmt.Sprintf("%s%d", logFilePrefix, i))
   260  		if err != nil {
   261  			c.Assert(err, IsNil)
   262  		}
   263  		fp.Close()
   264  	}
   265  }
   266  
   267  func (s *TestDBSSuite) startServer(i int, fp *os.File) (*server, error) {
   268  	cmd := exec.Command("dbstest_milevadb-server",
   269  		"--causetstore=einsteindb",
   270  		fmt.Sprintf("-L=%s", *dbsServerLogLevel),
   271  		fmt.Sprintf("--path=%s%s", *etcd, *einsteindbPath),
   272  		fmt.Sprintf("-P=%d", *startPort+i),
   273  		fmt.Sprintf("--status=%d", *statusPort+i),
   274  		fmt.Sprintf("--lease=%d", *lease))
   275  	cmd.Stderr = fp
   276  	cmd.Stdout = fp
   277  	err := cmd.Start()
   278  	if err != nil {
   279  		return nil, errors.Trace(err)
   280  	}
   281  	time.Sleep(500 * time.Millisecond)
   282  
   283  	// Make sure milevadb server process is started.
   284  	ps := fmt.Sprintf("ps -aux|grep dbstest_milevadb|grep %d", *startPort+i)
   285  	output, _ := exec.Command("sh", "-c", ps).Output()
   286  	if !strings.Contains(string(output), "dbstest_milevadb-server") {
   287  		time.Sleep(1 * time.Second)
   288  	}
   289  
   290  	// Open database.
   291  	var EDB *allegrosql.EDB
   292  	addr := fmt.Sprintf("%s:%d", *milevadbIP, *startPort+i)
   293  	sleepTime := time.Millisecond * 250
   294  	startTime := time.Now()
   295  	for i := 0; i < s.retryCount; i++ {
   296  		EDB, err = allegrosql.Open("allegrosql", fmt.Sprintf("root@(%s)/test_dbs", addr))
   297  		if err != nil {
   298  			log.Warnf("open addr %v failed, retry count %d err %v", addr, i, err)
   299  			continue
   300  		}
   301  		err = EDB.Ping()
   302  		if err == nil {
   303  			break
   304  		}
   305  		log.Warnf("ping addr %v failed, retry count %d err %v", addr, i, err)
   306  
   307  		EDB.Close()
   308  		time.Sleep(sleepTime)
   309  		sleepTime += sleepTime
   310  	}
   311  	if err != nil {
   312  		log.Errorf("restart server addr %v failed %v, take time %v", addr, err, time.Since(startTime))
   313  		return nil, errors.Trace(err)
   314  	}
   315  	EDB.SetMaxOpenConns(10)
   316  
   317  	_, err = EDB.InterDirc("use test_dbs")
   318  	if err != nil {
   319  		return nil, errors.Trace(err)
   320  	}
   321  
   322  	log.Infof("start server %s ok %v", addr, err)
   323  
   324  	return &server{
   325  		Cmd:   cmd,
   326  		EDB:   EDB,
   327  		addr:  addr,
   328  		logFP: fp,
   329  	}, nil
   330  }
   331  
   332  func (s *TestDBSSuite) restartServerRand() error {
   333  	i := rand.Intn(*serverNum)
   334  
   335  	s.m.Lock()
   336  	defer s.m.Unlock()
   337  
   338  	if s.procs[i] == nil {
   339  		return nil
   340  	}
   341  
   342  	server := s.procs[i]
   343  	s.procs[i] = nil
   344  	log.Warnf("begin to restart %s", server.addr)
   345  	err := s.killServer(server.Process)
   346  	if err != nil {
   347  		return errors.Trace(err)
   348  	}
   349  
   350  	s.procs[i], err = s.startServer(i, server.logFP)
   351  	return errors.Trace(err)
   352  }
   353  
   354  func isRetryError(err error) bool {
   355  	if err == nil {
   356  		return false
   357  	}
   358  
   359  	if terror.ErrorEqual(err, driver.ErrBadConn) ||
   360  		strings.Contains(err.Error(), "connection refused") ||
   361  		strings.Contains(err.Error(), "getsockopt: connection reset by peer") ||
   362  		strings.Contains(err.Error(), "KV error safe to retry") ||
   363  		strings.Contains(err.Error(), "try again later") ||
   364  		strings.Contains(err.Error(), "invalid connection") {
   365  		return true
   366  	}
   367  
   368  	// TODO: Check the specific columns number.
   369  	if strings.Contains(err.Error(), "DeferredCauset count doesn't match value count at event") {
   370  		log.Warnf("err is %v", err)
   371  		return false
   372  	}
   373  
   374  	log.Errorf("err is %v, can not retry", err)
   375  
   376  	return false
   377  }
   378  
   379  func (s *TestDBSSuite) exec(query string, args ...interface{}) (allegrosql.Result, error) {
   380  	for {
   381  		server := s.getServer()
   382  		r, err := server.EDB.InterDirc(query, args...)
   383  		if isRetryError(err) {
   384  			log.Errorf("exec %s in server %s err %v, retry", query, err, server.addr)
   385  			continue
   386  		}
   387  
   388  		return r, err
   389  	}
   390  }
   391  
   392  func (s *TestDBSSuite) mustInterDirc(c *C, query string, args ...interface{}) allegrosql.Result {
   393  	r, err := s.exec(query, args...)
   394  	if err != nil {
   395  		log.Fatalf("[mustInterDirc fail]query - %v %v, error - %v", query, args, err)
   396  	}
   397  
   398  	return r
   399  }
   400  
   401  func (s *TestDBSSuite) execInsert(c *C, query string, args ...interface{}) allegrosql.Result {
   402  	for {
   403  		r, err := s.exec(query, args...)
   404  		if err == nil {
   405  			return r
   406  		}
   407  
   408  		if *enableRestart {
   409  			// If use enable random restart servers, we should ignore key exists error.
   410  			if strings.Contains(err.Error(), "Duplicate entry") &&
   411  				strings.Contains(err.Error(), "for key") {
   412  				return r
   413  			}
   414  		}
   415  
   416  		log.Fatalf("[execInsert fail]query - %v %v, error - %v", query, args, err)
   417  	}
   418  }
   419  
   420  func (s *TestDBSSuite) query(query string, args ...interface{}) (*allegrosql.Rows, error) {
   421  	for {
   422  		server := s.getServer()
   423  		r, err := server.EDB.Query(query, args...)
   424  		if isRetryError(err) {
   425  			log.Errorf("query %s in server %s err %v, retry", query, err, server.addr)
   426  			continue
   427  		}
   428  
   429  		return r, err
   430  	}
   431  }
   432  
   433  func (s *TestDBSSuite) getServer() *server {
   434  	s.m.Lock()
   435  	defer s.m.Unlock()
   436  
   437  	for i := 0; i < 20; i++ {
   438  		i := rand.Intn(*serverNum)
   439  
   440  		if s.procs[i] != nil {
   441  			return s.procs[i]
   442  		}
   443  	}
   444  
   445  	log.Fatalf("try to get server too many times")
   446  	return nil
   447  }
   448  
   449  // runDBS executes the DBS query, returns a channel so that you can use it to wait DBS finished.
   450  func (s *TestDBSSuite) runDBS(allegrosql string) chan error {
   451  	done := make(chan error, 1)
   452  	go func() {
   453  		_, err := s.s.InterDircute(goctx.Background(), allegrosql)
   454  		// We must wait 2 * lease time to guarantee all servers uFIDelate the schemaReplicant.
   455  		if err == nil {
   456  			time.Sleep(time.Duration(*lease) * time.Second * 2)
   457  		}
   458  
   459  		done <- err
   460  	}()
   461  
   462  	return done
   463  }
   464  
   465  func (s *TestDBSSuite) getTable(c *C, name string) causet.Block {
   466  	tbl, err := petri.GetPetri(s.ctx).SchemaReplicant().TableByName(perceptron.NewCIStr("test_dbs"), perceptron.NewCIStr(name))
   467  	c.Assert(err, IsNil)
   468  	return tbl
   469  }
   470  
   471  func dumpRows(c *C, rows *allegrosql.Rows) [][]interface{} {
   472  	defcaus, err := rows.DeferredCausets()
   473  	c.Assert(err, IsNil)
   474  	var ay [][]interface{}
   475  	for rows.Next() {
   476  		v := make([]interface{}, len(defcaus))
   477  		for i := range v {
   478  			v[i] = new(interface{})
   479  		}
   480  		err = rows.Scan(v...)
   481  		c.Assert(err, IsNil)
   482  
   483  		for i := range v {
   484  			v[i] = *(v[i].(*interface{}))
   485  		}
   486  		ay = append(ay, v)
   487  	}
   488  
   489  	rows.Close()
   490  	c.Assert(rows.Err(), IsNil, Commentf("%v", ay))
   491  	return ay
   492  }
   493  
   494  func matchRows(c *C, rows *allegrosql.Rows, expected [][]interface{}) {
   495  	ay := dumpRows(c, rows)
   496  	c.Assert(len(ay), Equals, len(expected), Commentf("%v", expected))
   497  	for i := range ay {
   498  		match(c, ay[i], expected[i]...)
   499  	}
   500  }
   501  
   502  func match(c *C, event []interface{}, expected ...interface{}) {
   503  	c.Assert(len(event), Equals, len(expected))
   504  	for i := range event {
   505  		if event[i] == nil {
   506  			c.Assert(expected[i], IsNil)
   507  			continue
   508  		}
   509  
   510  		got, err := types.ToString(event[i])
   511  		c.Assert(err, IsNil)
   512  
   513  		need, err := types.ToString(expected[i])
   514  		c.Assert(err, IsNil)
   515  		c.Assert(got, Equals, need)
   516  	}
   517  }
   518  
   519  func (s *TestDBSSuite) Bootstrap(c *C) {
   520  	tk := testkit.NewTestKit(c, s.causetstore)
   521  	tk.MustInterDirc("use test_dbs")
   522  	tk.MustInterDirc("drop causet if exists test_index, test_column, test_insert, test_conflict_insert, " +
   523  		"test_uFIDelate, test_conflict_uFIDelate, test_delete, test_conflict_delete, test_mixed, test_inc")
   524  
   525  	tk.MustInterDirc("create causet test_index (c int, c1 bigint, c2 double, c3 varchar(256), primary key(c))")
   526  	tk.MustInterDirc("create causet test_column (c1 int, c2 int, primary key(c1))")
   527  	tk.MustInterDirc("create causet test_insert (c1 int, c2 int, primary key(c1))")
   528  	tk.MustInterDirc("create causet test_conflict_insert (c1 int, c2 int, primary key(c1))")
   529  	tk.MustInterDirc("create causet test_uFIDelate (c1 int, c2 int, primary key(c1))")
   530  	tk.MustInterDirc("create causet test_conflict_uFIDelate (c1 int, c2 int, primary key(c1))")
   531  	tk.MustInterDirc("create causet test_delete (c1 int, c2 int, primary key(c1))")
   532  	tk.MustInterDirc("create causet test_conflict_delete (c1 int, c2 int, primary key(c1))")
   533  	tk.MustInterDirc("create causet test_mixed (c1 int, c2 int, primary key(c1))")
   534  	tk.MustInterDirc("create causet test_inc (c1 int, c2 int, primary key(c1))")
   535  
   536  	tk.MustInterDirc("set @@milevadb_enable_clustered_index = 1")
   537  	tk.MustInterDirc("drop causet if exists test_insert_common, test_conflict_insert_common, " +
   538  		"test_uFIDelate_common, test_conflict_uFIDelate_common, test_delete_common, test_conflict_delete_common, " +
   539  		"test_mixed_common, test_inc_common")
   540  	tk.MustInterDirc("create causet test_insert_common (c1 int, c2 int, primary key(c1, c2))")
   541  	tk.MustInterDirc("create causet test_conflict_insert_common (c1 int, c2 int, primary key(c1, c2))")
   542  	tk.MustInterDirc("create causet test_uFIDelate_common (c1 int, c2 int, primary key(c1, c2))")
   543  	tk.MustInterDirc("create causet test_conflict_uFIDelate_common (c1 int, c2 int, primary key(c1, c2))")
   544  	tk.MustInterDirc("create causet test_delete_common (c1 int, c2 int, primary key(c1, c2))")
   545  	tk.MustInterDirc("create causet test_conflict_delete_common (c1 int, c2 int, primary key(c1, c2))")
   546  	tk.MustInterDirc("create causet test_mixed_common (c1 int, c2 int, primary key(c1, c2))")
   547  	tk.MustInterDirc("create causet test_inc_common (c1 int, c2 int, primary key(c1, c2))")
   548  	tk.MustInterDirc("set @@milevadb_enable_clustered_index = 0")
   549  }
   550  
   551  func (s *TestDBSSuite) TestSimple(c *C) {
   552  	done := s.runDBS("create causet if not exists test_simple (c1 int, c2 int, c3 int)")
   553  	err := <-done
   554  	c.Assert(err, IsNil)
   555  
   556  	_, err = s.exec("insert into test_simple values (1, 1, 1)")
   557  	c.Assert(err, IsNil)
   558  
   559  	rows, err := s.query("select c1 from test_simple limit 1")
   560  	c.Assert(err, IsNil)
   561  	matchRows(c, rows, [][]interface{}{{1}})
   562  
   563  	done = s.runDBS("drop causet if exists test_simple")
   564  	err = <-done
   565  	c.Assert(err, IsNil)
   566  }
   567  
   568  func (s *TestDBSSuite) TestSimpleInsert(c *C) {
   569  	tblName := "test_insert"
   570  	if s.IsCommonHandle {
   571  		tblName = "test_insert_common"
   572  	}
   573  
   574  	workerNum := 10
   575  	rowCount := 10000
   576  	batch := rowCount / workerNum
   577  
   578  	start := time.Now()
   579  
   580  	var wg sync.WaitGroup
   581  	wg.Add(workerNum)
   582  	for i := 0; i < workerNum; i++ {
   583  		go func(i int) {
   584  			defer wg.Done()
   585  
   586  			for j := 0; j < batch; j++ {
   587  				k := batch*i + j
   588  				s.execInsert(c, fmt.Sprintf("insert into %s values (%d, %d)", tblName, k, k))
   589  			}
   590  		}(i)
   591  	}
   592  	wg.Wait()
   593  
   594  	end := time.Now()
   595  	fmt.Printf("[TestSimpleInsert][Time Cost]%v\n", end.Sub(start))
   596  
   597  	ctx := s.ctx
   598  	err := ctx.NewTxn(goctx.Background())
   599  	c.Assert(err, IsNil)
   600  
   601  	tbl := s.getTable(c, "test_insert")
   602  	handles := ekv.NewHandleMap()
   603  	err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
   604  		handles.Set(h, struct{}{})
   605  		c.Assert(data[0].GetValue(), Equals, data[1].GetValue())
   606  		return true, nil
   607  	})
   608  	c.Assert(err, IsNil)
   609  	c.Assert(handles.Len(), Equals, rowCount, Commentf("%d %d", handles.Len(), rowCount))
   610  	s.RerunWithCommonHandleEnabled(c, s.TestSimpleInsert)
   611  }
   612  
   613  func (s *TestDBSSuite) TestSimpleConflictInsert(c *C) {
   614  	tblName := "test_conflict_insert"
   615  	if s.IsCommonHandle {
   616  		tblName = "test_conflict_insert_common"
   617  	}
   618  
   619  	var mu sync.Mutex
   620  	keysMap := make(map[int64]int64)
   621  
   622  	workerNum := 10
   623  	rowCount := 10000
   624  	batch := rowCount / workerNum
   625  
   626  	start := time.Now()
   627  
   628  	var wg sync.WaitGroup
   629  	wg.Add(workerNum)
   630  	for i := 0; i < workerNum; i++ {
   631  		go func() {
   632  			defer wg.Done()
   633  
   634  			for j := 0; j < batch; j++ {
   635  				k := randomNum(rowCount)
   636  				s.exec(fmt.Sprintf("insert into %s values (%d, %d)", tblName, k, k))
   637  				mu.Lock()
   638  				keysMap[int64(k)] = int64(k)
   639  				mu.Unlock()
   640  			}
   641  		}()
   642  	}
   643  	wg.Wait()
   644  
   645  	end := time.Now()
   646  	fmt.Printf("[TestSimpleConflictInsert][Time Cost]%v\n", end.Sub(start))
   647  
   648  	ctx := s.ctx
   649  	err := ctx.NewTxn(goctx.Background())
   650  	c.Assert(err, IsNil)
   651  
   652  	tbl := s.getTable(c, tblName)
   653  	handles := ekv.NewHandleMap()
   654  	err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
   655  		handles.Set(h, struct{}{})
   656  		c.Assert(keysMap, HasKey, data[0].GetValue())
   657  		c.Assert(data[0].GetValue(), Equals, data[1].GetValue())
   658  		return true, nil
   659  	})
   660  	c.Assert(err, IsNil)
   661  	c.Assert(handles.Len(), Equals, len(keysMap))
   662  	s.RerunWithCommonHandleEnabled(c, s.TestSimpleConflictInsert)
   663  }
   664  
   665  func (s *TestDBSSuite) TestSimpleUFIDelate(c *C) {
   666  	tblName := "test_uFIDelate"
   667  	if s.IsCommonHandle {
   668  		tblName = "test_uFIDelate_common"
   669  	}
   670  	var mu sync.Mutex
   671  	keysMap := make(map[int64]int64)
   672  
   673  	workerNum := 10
   674  	rowCount := 10000
   675  	batch := rowCount / workerNum
   676  
   677  	start := time.Now()
   678  
   679  	var wg sync.WaitGroup
   680  	wg.Add(workerNum)
   681  	for i := 0; i < workerNum; i++ {
   682  		go func(i int) {
   683  			defer wg.Done()
   684  
   685  			for j := 0; j < batch; j++ {
   686  				k := batch*i + j
   687  				s.execInsert(c, fmt.Sprintf("insert into %s values (%d, %d)", tblName, k, k))
   688  				v := randomNum(rowCount)
   689  				s.mustInterDirc(c, fmt.Sprintf("uFIDelate %s set c2 = %d where c1 = %d", tblName, v, k))
   690  				mu.Lock()
   691  				keysMap[int64(k)] = int64(v)
   692  				mu.Unlock()
   693  			}
   694  		}(i)
   695  	}
   696  	wg.Wait()
   697  
   698  	end := time.Now()
   699  	fmt.Printf("[TestSimpleUFIDelate][Time Cost]%v\n", end.Sub(start))
   700  
   701  	ctx := s.ctx
   702  	err := ctx.NewTxn(goctx.Background())
   703  	c.Assert(err, IsNil)
   704  
   705  	tbl := s.getTable(c, tblName)
   706  	handles := ekv.NewHandleMap()
   707  	err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
   708  		handles.Set(h, struct{}{})
   709  		key := data[0].GetInt64()
   710  		c.Assert(data[1].GetValue(), Equals, keysMap[key])
   711  		return true, nil
   712  	})
   713  	c.Assert(err, IsNil)
   714  	c.Assert(handles.Len(), Equals, rowCount)
   715  	s.RerunWithCommonHandleEnabled(c, s.TestSimpleUFIDelate)
   716  }
   717  
   718  func (s *TestDBSSuite) TestSimpleConflictUFIDelate(c *C) {
   719  	tblName := "test_conflict_uFIDelate"
   720  	if s.IsCommonHandle {
   721  		tblName = "test_conflict_uFIDelate_common"
   722  	}
   723  	var mu sync.Mutex
   724  	keysMap := make(map[int64]int64)
   725  
   726  	workerNum := 10
   727  	rowCount := 10000
   728  	batch := rowCount / workerNum
   729  
   730  	start := time.Now()
   731  
   732  	var wg sync.WaitGroup
   733  	wg.Add(workerNum)
   734  	for i := 0; i < workerNum; i++ {
   735  		go func(i int) {
   736  			defer wg.Done()
   737  
   738  			for j := 0; j < batch; j++ {
   739  				k := batch*i + j
   740  				s.execInsert(c, fmt.Sprintf("insert into %s values (%d, %d)", tblName, k, k))
   741  				mu.Lock()
   742  				keysMap[int64(k)] = int64(k)
   743  				mu.Unlock()
   744  			}
   745  		}(i)
   746  	}
   747  	wg.Wait()
   748  
   749  	end := time.Now()
   750  	fmt.Printf("[TestSimpleConflictUFIDelate][Insert][Time Cost]%v\n", end.Sub(start))
   751  
   752  	start = time.Now()
   753  
   754  	defaultValue := int64(-1)
   755  	wg.Add(workerNum)
   756  	for i := 0; i < workerNum; i++ {
   757  		go func() {
   758  			defer wg.Done()
   759  
   760  			for j := 0; j < batch; j++ {
   761  				k := randomNum(rowCount)
   762  				s.mustInterDirc(c, fmt.Sprintf("uFIDelate %s set c2 = %d where c1 = %d", tblName, defaultValue, k))
   763  				mu.Lock()
   764  				keysMap[int64(k)] = defaultValue
   765  				mu.Unlock()
   766  			}
   767  		}()
   768  	}
   769  	wg.Wait()
   770  
   771  	end = time.Now()
   772  	fmt.Printf("[TestSimpleConflictUFIDelate][UFIDelate][Time Cost]%v\n", end.Sub(start))
   773  
   774  	ctx := s.ctx
   775  	err := ctx.NewTxn(goctx.Background())
   776  	c.Assert(err, IsNil)
   777  
   778  	tbl := s.getTable(c, tblName)
   779  	handles := ekv.NewHandleMap()
   780  	err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
   781  		handles.Set(h, struct{}{})
   782  		c.Assert(keysMap, HasKey, data[0].GetValue())
   783  
   784  		if !reflect.DeepEqual(data[1].GetValue(), data[0].GetValue()) && !reflect.DeepEqual(data[1].GetValue(), defaultValue) {
   785  			log.Fatalf("[TestSimpleConflictUFIDelate fail]Bad event: %v", data)
   786  		}
   787  
   788  		return true, nil
   789  	})
   790  	c.Assert(err, IsNil)
   791  	c.Assert(handles.Len(), Equals, rowCount)
   792  	s.RerunWithCommonHandleEnabled(c, s.TestSimpleConflictUFIDelate)
   793  }
   794  
   795  func (s *TestDBSSuite) TestSimpleDelete(c *C) {
   796  	tblName := "test_delete"
   797  	if s.IsCommonHandle {
   798  		tblName = "test_delete_common"
   799  	}
   800  	workerNum := 10
   801  	rowCount := 10000
   802  	batch := rowCount / workerNum
   803  
   804  	start := time.Now()
   805  
   806  	var wg sync.WaitGroup
   807  	wg.Add(workerNum)
   808  	for i := 0; i < workerNum; i++ {
   809  		go func(i int) {
   810  			defer wg.Done()
   811  
   812  			for j := 0; j < batch; j++ {
   813  				k := batch*i + j
   814  				s.execInsert(c, fmt.Sprintf("insert into %s values (%d, %d)", tblName, k, k))
   815  				s.mustInterDirc(c, fmt.Sprintf("delete from %s where c1 = %d", tblName, k))
   816  			}
   817  		}(i)
   818  	}
   819  	wg.Wait()
   820  
   821  	end := time.Now()
   822  	fmt.Printf("[TestSimpleDelete][Time Cost]%v\n", end.Sub(start))
   823  
   824  	ctx := s.ctx
   825  	err := ctx.NewTxn(goctx.Background())
   826  	c.Assert(err, IsNil)
   827  
   828  	tbl := s.getTable(c, tblName)
   829  	handles := ekv.NewHandleMap()
   830  	err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
   831  		handles.Set(h, struct{}{})
   832  		return true, nil
   833  	})
   834  	c.Assert(err, IsNil)
   835  	c.Assert(handles.Len(), Equals, 0)
   836  	s.RerunWithCommonHandleEnabled(c, s.TestSimpleDelete)
   837  }
   838  
   839  func (s *TestDBSSuite) TestSimpleConflictDelete(c *C) {
   840  	tblName := "test_conflict_delete"
   841  	if s.IsCommonHandle {
   842  		tblName = "test_conflict_delete_common"
   843  	}
   844  	var mu sync.Mutex
   845  	keysMap := make(map[int64]int64)
   846  
   847  	workerNum := 10
   848  	rowCount := 10000
   849  	batch := rowCount / workerNum
   850  
   851  	start := time.Now()
   852  
   853  	var wg sync.WaitGroup
   854  	wg.Add(workerNum)
   855  	for i := 0; i < workerNum; i++ {
   856  		go func(i int) {
   857  			defer wg.Done()
   858  
   859  			for j := 0; j < batch; j++ {
   860  				k := batch*i + j
   861  				s.execInsert(c, fmt.Sprintf("insert into %s values (%d, %d)", tblName, k, k))
   862  				mu.Lock()
   863  				keysMap[int64(k)] = int64(k)
   864  				mu.Unlock()
   865  			}
   866  		}(i)
   867  	}
   868  	wg.Wait()
   869  
   870  	end := time.Now()
   871  	fmt.Printf("[TestSimpleConflictDelete][Insert][Time Cost]%v\n", end.Sub(start))
   872  
   873  	start = time.Now()
   874  
   875  	wg.Add(workerNum)
   876  	for i := 0; i < workerNum; i++ {
   877  		go func(i int) {
   878  			defer wg.Done()
   879  
   880  			for j := 0; j < batch; j++ {
   881  				k := randomNum(rowCount)
   882  				s.mustInterDirc(c, fmt.Sprintf("delete from %s where c1 = %d", tblName, k))
   883  				mu.Lock()
   884  				delete(keysMap, int64(k))
   885  				mu.Unlock()
   886  			}
   887  		}(i)
   888  	}
   889  	wg.Wait()
   890  
   891  	end = time.Now()
   892  	fmt.Printf("[TestSimpleConflictDelete][Delete][Time Cost]%v\n", end.Sub(start))
   893  
   894  	ctx := s.ctx
   895  	err := ctx.NewTxn(goctx.Background())
   896  	c.Assert(err, IsNil)
   897  
   898  	tbl := s.getTable(c, tblName)
   899  	handles := ekv.NewHandleMap()
   900  	err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
   901  		handles.Set(h, struct{}{})
   902  		c.Assert(keysMap, HasKey, data[0].GetValue())
   903  		return true, nil
   904  	})
   905  	c.Assert(err, IsNil)
   906  	c.Assert(handles.Len(), Equals, len(keysMap))
   907  	s.RerunWithCommonHandleEnabled(c, s.TestSimpleConflictDelete)
   908  }
   909  
   910  func (s *TestDBSSuite) TestSimpleMixed(c *C) {
   911  	tblName := "test_mixed"
   912  	if s.IsCommonHandle {
   913  		tblName = "test_mixed_common"
   914  	}
   915  	workerNum := 10
   916  	rowCount := 10000
   917  	batch := rowCount / workerNum
   918  
   919  	start := time.Now()
   920  
   921  	var wg sync.WaitGroup
   922  	wg.Add(workerNum)
   923  	for i := 0; i < workerNum; i++ {
   924  		go func(i int) {
   925  			defer wg.Done()
   926  
   927  			for j := 0; j < batch; j++ {
   928  				k := batch*i + j
   929  				s.execInsert(c, fmt.Sprintf("insert into %s values (%d, %d)", tblName, k, k))
   930  			}
   931  		}(i)
   932  	}
   933  	wg.Wait()
   934  
   935  	end := time.Now()
   936  	fmt.Printf("[TestSimpleMixed][Insert][Time Cost]%v\n", end.Sub(start))
   937  
   938  	start = time.Now()
   939  
   940  	rowID := int64(rowCount)
   941  	defaultValue := int64(-1)
   942  
   943  	wg.Add(workerNum)
   944  	for i := 0; i < workerNum; i++ {
   945  		go func() {
   946  			defer wg.Done()
   947  
   948  			for j := 0; j < batch; j++ {
   949  				key := atomic.AddInt64(&rowID, 1)
   950  				s.execInsert(c, fmt.Sprintf("insert into %s values (%d, %d)", tblName, key, key))
   951  				key = int64(randomNum(rowCount))
   952  				s.mustInterDirc(c, fmt.Sprintf("uFIDelate %s set c2 = %d where c1 = %d", tblName, defaultValue, key))
   953  				key = int64(randomNum(rowCount))
   954  				s.mustInterDirc(c, fmt.Sprintf("delete from %s where c1 = %d", tblName, key))
   955  			}
   956  		}()
   957  	}
   958  	wg.Wait()
   959  
   960  	end = time.Now()
   961  	fmt.Printf("[TestSimpleMixed][Mixed][Time Cost]%v\n", end.Sub(start))
   962  
   963  	ctx := s.ctx
   964  	err := ctx.NewTxn(goctx.Background())
   965  	c.Assert(err, IsNil)
   966  
   967  	tbl := s.getTable(c, tblName)
   968  	uFIDelateCount := int64(0)
   969  	insertCount := int64(0)
   970  	err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
   971  		if reflect.DeepEqual(data[1].GetValue(), data[0].GetValue()) {
   972  			insertCount++
   973  		} else if reflect.DeepEqual(data[1].GetValue(), defaultValue) && data[0].GetInt64() < int64(rowCount) {
   974  			uFIDelateCount++
   975  		} else {
   976  			log.Fatalf("[TestSimpleMixed fail]invalid event: %v", data)
   977  		}
   978  
   979  		return true, nil
   980  	})
   981  	c.Assert(err, IsNil)
   982  
   983  	deleteCount := atomic.LoadInt64(&rowID) - insertCount - uFIDelateCount
   984  	c.Assert(insertCount, Greater, int64(0))
   985  	c.Assert(uFIDelateCount, Greater, int64(0))
   986  	c.Assert(deleteCount, Greater, int64(0))
   987  	s.RerunWithCommonHandleEnabled(c, s.TestSimpleMixed)
   988  }
   989  
   990  func (s *TestDBSSuite) TestSimpleInc(c *C) {
   991  	tblName := "test_inc"
   992  	if s.IsCommonHandle {
   993  		tblName = "test_inc_common"
   994  	}
   995  	workerNum := 10
   996  	rowCount := 1000
   997  	batch := rowCount / workerNum
   998  
   999  	start := time.Now()
  1000  
  1001  	var wg sync.WaitGroup
  1002  	wg.Add(workerNum)
  1003  	for i := 0; i < workerNum; i++ {
  1004  		go func(i int) {
  1005  			defer wg.Done()
  1006  
  1007  			for j := 0; j < batch; j++ {
  1008  				k := batch*i + j
  1009  				s.execInsert(c, fmt.Sprintf("insert into %s values (%d, %d)", tblName, k, k))
  1010  			}
  1011  		}(i)
  1012  	}
  1013  	wg.Wait()
  1014  
  1015  	end := time.Now()
  1016  	fmt.Printf("[TestSimpleInc][Insert][Time Cost]%v\n", end.Sub(start))
  1017  
  1018  	start = time.Now()
  1019  
  1020  	wg.Add(workerNum)
  1021  	for i := 0; i < workerNum; i++ {
  1022  		go func() {
  1023  			defer wg.Done()
  1024  
  1025  			for j := 0; j < batch; j++ {
  1026  				s.mustInterDirc(c, fmt.Sprintf("uFIDelate %s set c2 = c2 + 1 where c1 = 0", tblName))
  1027  			}
  1028  		}()
  1029  	}
  1030  	wg.Wait()
  1031  
  1032  	end = time.Now()
  1033  	fmt.Printf("[TestSimpleInc][UFIDelate][Time Cost]%v\n", end.Sub(start))
  1034  
  1035  	ctx := s.ctx
  1036  	err := ctx.NewTxn(goctx.Background())
  1037  	c.Assert(err, IsNil)
  1038  
  1039  	tbl := s.getTable(c, "test_inc")
  1040  	err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) {
  1041  		if reflect.DeepEqual(data[0].GetValue(), int64(0)) {
  1042  			if *enableRestart {
  1043  				c.Assert(data[1].GetValue(), GreaterEqual, int64(rowCount))
  1044  			} else {
  1045  				c.Assert(data[1].GetValue(), Equals, int64(rowCount))
  1046  			}
  1047  		} else {
  1048  			c.Assert(data[0].GetValue(), Equals, data[1].GetValue())
  1049  		}
  1050  
  1051  		return true, nil
  1052  	})
  1053  	c.Assert(err, IsNil)
  1054  	s.RerunWithCommonHandleEnabled(c, s.TestSimpleInc)
  1055  }
  1056  
  1057  // addEnvPath appends newPath to $PATH.
  1058  func addEnvPath(newPath string) {
  1059  	os.Setenv("PATH", fmt.Sprintf("%s%c%s", os.Getenv("PATH"), os.PathListSeparator, newPath))
  1060  }
  1061  
  1062  func init() {
  1063  	rand.Seed(time.Now().UnixNano())
  1064  	causetstore.Register("einsteindb", einsteindb.Driver{})
  1065  }