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 }