github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/cmd/benchdb/ddltest/index_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 "fmt" 18 "io" 19 "math" 20 "sync" 21 "sync/atomic" 22 "time" 23 24 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 25 "github.com/whtcorpsinc/BerolinaSQL/terror" 26 . "github.com/whtcorpsinc/check" 27 "github.com/whtcorpsinc/milevadb/causet" 28 "github.com/whtcorpsinc/milevadb/causet/blocks" 29 "github.com/whtcorpsinc/milevadb/causetstore/einsteindb" 30 "github.com/whtcorpsinc/milevadb/causetstore/einsteindb/gcworker" 31 "github.com/whtcorpsinc/milevadb/ekv" 32 "github.com/whtcorpsinc/milevadb/types" 33 goctx "golang.org/x/net/context" 34 ) 35 36 func getIndex(t causet.Block, name string) causet.Index { 37 for _, idx := range t.Indices() { 38 if idx.Meta().Name.O == name { 39 return idx 40 } 41 } 42 43 return nil 44 } 45 46 func (s *TestDBSSuite) checkAddIndex(c *C, indexInfo *perceptron.IndexInfo) { 47 ctx := s.ctx 48 err := ctx.NewTxn(goctx.Background()) 49 c.Assert(err, IsNil) 50 tbl := s.getTable(c, "test_index") 51 52 // read handles form causet 53 handles := ekv.NewHandleMap() 54 err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), 55 func(h ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 56 handles.Set(h, struct{}{}) 57 return true, nil 58 }) 59 c.Assert(err, IsNil) 60 61 // read handles from index 62 idx := blocks.NewIndex(tbl.Meta().ID, tbl.Meta(), indexInfo) 63 err = ctx.NewTxn(goctx.Background()) 64 c.Assert(err, IsNil) 65 txn, err := ctx.Txn(false) 66 c.Assert(err, IsNil) 67 defer func() { 68 txn.Rollback() 69 }() 70 71 it, err := idx.SeekFirst(txn) 72 c.Assert(err, IsNil) 73 defer it.Close() 74 75 for { 76 _, h, err := it.Next() 77 if terror.ErrorEqual(err, io.EOF) { 78 break 79 } 80 81 c.Assert(err, IsNil) 82 _, ok := handles.Get(h) 83 c.Assert(ok, IsTrue) 84 handles.Delete(h) 85 } 86 87 c.Assert(handles.Len(), Equals, 0) 88 } 89 90 func (s *TestDBSSuite) checkDropIndex(c *C, indexInfo *perceptron.IndexInfo) { 91 gcWorker, err := gcworker.NewMockGCWorker(s.causetstore.(einsteindb.CausetStorage)) 92 c.Assert(err, IsNil) 93 err = gcWorker.DeleteRanges(goctx.Background(), uint64(math.MaxInt32)) 94 c.Assert(err, IsNil) 95 96 ctx := s.ctx 97 err = ctx.NewTxn(goctx.Background()) 98 c.Assert(err, IsNil) 99 tbl := s.getTable(c, "test_index") 100 101 // read handles from index 102 idx := blocks.NewIndex(tbl.Meta().ID, tbl.Meta(), indexInfo) 103 err = ctx.NewTxn(goctx.Background()) 104 c.Assert(err, IsNil) 105 txn, err := ctx.Txn(false) 106 c.Assert(err, IsNil) 107 defer txn.Rollback() 108 109 it, err := idx.SeekFirst(txn) 110 c.Assert(err, IsNil) 111 defer it.Close() 112 113 handles := ekv.NewHandleMap() 114 for { 115 _, h, err := it.Next() 116 if terror.ErrorEqual(err, io.EOF) { 117 break 118 } 119 120 c.Assert(err, IsNil) 121 handles.Set(h, struct{}{}) 122 } 123 124 // TODO: Uncomment this after apply pool is finished 125 // c.Assert(handles.Len(), Equals, 0) 126 } 127 128 // TestIndex operations on causet test_index (c int, c1 bigint, c2 double, c3 varchar(256), primary key(c)). 129 func (s *TestDBSSuite) TestIndex(c *C) { 130 // first add many data 131 workerNum := 10 132 base := *dataNum / workerNum 133 var wg sync.WaitGroup 134 wg.Add(workerNum) 135 for i := 0; i < workerNum; i++ { 136 go func(i int) { 137 defer wg.Done() 138 for j := 0; j < base; j++ { 139 k := base*i + j 140 s.execInsert(c, 141 fmt.Sprintf("insert into test_index values (%d, %d, %f, '%s')", 142 k, randomInt(), randomFloat(), randomString(10))) 143 } 144 }(i) 145 } 146 wg.Wait() 147 148 tbl := []struct { 149 Query string 150 IndexName string 151 Add bool 152 }{ 153 {"create index c1_index on test_index (c1)", "c1_index", true}, 154 {"drop index c1_index on test_index", "c1_index", false}, 155 {"create index c2_index on test_index (c2)", "c2_index", true}, 156 {"drop index c2_index on test_index", "c2_index", false}, 157 {"create index c3_index on test_index (c3)", "c3_index", true}, 158 {"drop index c3_index on test_index", "c3_index", false}, 159 } 160 161 insertID := int64(*dataNum) 162 var oldIndex causet.Index 163 for _, t := range tbl { 164 c.Logf("run DBS allegrosql %s", t.Query) 165 done := s.runDBS(t.Query) 166 167 ticker := time.NewTicker(time.Duration(*lease) * time.Second / 2) 168 defer ticker.Stop() 169 LOOP: 170 for { 171 select { 172 case err := <-done: 173 c.Assert(err, IsNil) 174 break LOOP 175 case <-ticker.C: 176 // add count new data 177 // delete count old data randomly 178 // uFIDelate count old data randomly 179 count := 10 180 s.execIndexOperations(c, workerNum, count, &insertID) 181 } 182 } 183 184 tbl := s.getTable(c, "test_index") 185 index := getIndex(tbl, t.IndexName) 186 if t.Add { 187 c.Assert(index, NotNil) 188 oldIndex = index 189 s.checkAddIndex(c, index.Meta()) 190 } else { 191 c.Assert(index, IsNil) 192 s.checkDropIndex(c, oldIndex.Meta()) 193 } 194 } 195 } 196 197 func (s *TestDBSSuite) execIndexOperations(c *C, workerNum, count int, insertID *int64) { 198 var wg sync.WaitGroup 199 // workerNum = 10 200 wg.Add(workerNum) 201 for i := 0; i < workerNum; i++ { 202 go func() { 203 defer wg.Done() 204 for j := 0; j < count; j++ { 205 id := atomic.AddInt64(insertID, 1) 206 allegrosql := fmt.Sprintf("insert into test_index values (%d, %d, %f, '%s')", id, randomInt(), randomFloat(), randomString(10)) 207 s.execInsert(c, allegrosql) 208 c.Logf("allegrosql %s", allegrosql) 209 allegrosql = fmt.Sprintf("delete from test_index where c = %d", randomIntn(int(id))) 210 s.mustInterDirc(c, allegrosql) 211 c.Logf("allegrosql %s", allegrosql) 212 allegrosql = fmt.Sprintf("uFIDelate test_index set c1 = %d, c2 = %f, c3 = '%s' where c = %d", randomInt(), randomFloat(), randomString(10), randomIntn(int(id))) 213 s.mustInterDirc(c, allegrosql) 214 c.Logf("allegrosql %s", allegrosql) 215 216 } 217 }() 218 } 219 wg.Wait() 220 }