github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/cmd/benchdb/ddltest/column_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 "reflect" 19 "sync" 20 "sync/atomic" 21 "time" 22 23 log "github.com/sirupsen/logrus" 24 "github.com/whtcorpsinc/BerolinaSQL/terror" 25 . "github.com/whtcorpsinc/check" 26 "github.com/whtcorpsinc/milevadb/causet" 27 causetembedded "github.com/whtcorpsinc/milevadb/causet/embedded" 28 "github.com/whtcorpsinc/milevadb/ekv" 29 "github.com/whtcorpsinc/milevadb/stochastik" 30 "github.com/whtcorpsinc/milevadb/types" 31 goctx "golang.org/x/net/context" 32 ) 33 34 // After add column finished, check the records in the causet. 35 func (s *TestDBSSuite) checkAddDeferredCauset(c *C, rowID int64, defaultVal interface{}, uFIDelatedVal interface{}) { 36 ctx := s.ctx 37 err := ctx.NewTxn(goctx.Background()) 38 c.Assert(err, IsNil) 39 40 tbl := s.getTable(c, "test_column") 41 oldInsertCount := int64(0) 42 newInsertCount := int64(0) 43 oldUFIDelateCount := int64(0) 44 newUFIDelateCount := int64(0) 45 err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 46 col1Val := data[0].GetValue() 47 col2Val := data[1].GetValue() 48 col3Val := data[2].GetValue() 49 // Check inserted event. 50 if reflect.DeepEqual(col1Val, col2Val) { 51 if reflect.DeepEqual(col3Val, defaultVal) { 52 // When insert a event with 2 columns, the third column will be default value. 53 oldInsertCount++ 54 } else if reflect.DeepEqual(col3Val, col1Val) { 55 // When insert a event with 3 columns, the third column value will be the first column value. 56 newInsertCount++ 57 } else { 58 log.Fatalf("[checkAddDeferredCauset fail]invalid event: %v", data) 59 } 60 } 61 62 // Check uFIDelated event. 63 if reflect.DeepEqual(col2Val, uFIDelatedVal) { 64 if reflect.DeepEqual(col3Val, defaultVal) || reflect.DeepEqual(col3Val, col1Val) { 65 oldUFIDelateCount++ 66 } else if reflect.DeepEqual(col3Val, uFIDelatedVal) { 67 newUFIDelateCount++ 68 } else { 69 log.Fatalf("[checkAddDeferredCauset fail]invalid event: %v", data) 70 } 71 } 72 73 return true, nil 74 }) 75 c.Assert(err, IsNil) 76 77 deleteCount := rowID - oldInsertCount - newInsertCount - oldUFIDelateCount - newUFIDelateCount 78 c.Assert(oldInsertCount, GreaterEqual, int64(0)) 79 c.Assert(newInsertCount, GreaterEqual, int64(0)) 80 c.Assert(oldUFIDelateCount, Greater, int64(0)) 81 c.Assert(newUFIDelateCount, Greater, int64(0)) 82 c.Assert(deleteCount, Greater, int64(0)) 83 } 84 85 func (s *TestDBSSuite) checkDropDeferredCauset(c *C, rowID int64, alterDeferredCauset *causet.DeferredCauset, uFIDelateDefault interface{}) { 86 ctx := s.ctx 87 err := ctx.NewTxn(goctx.Background()) 88 c.Assert(err, IsNil) 89 90 tbl := s.getTable(c, "test_column") 91 for _, col := range tbl.DefCauss() { 92 c.Assert(col.ID, Not(Equals), alterDeferredCauset.ID) 93 } 94 insertCount := int64(0) 95 uFIDelateCount := int64(0) 96 err = tbl.IterRecords(ctx, tbl.FirstKey(), tbl.DefCauss(), func(_ ekv.Handle, data []types.Causet, defcaus []*causet.DeferredCauset) (bool, error) { 97 if reflect.DeepEqual(data[1].GetValue(), data[0].GetValue()) { 98 // Check inserted event. 99 insertCount++ 100 } else if reflect.DeepEqual(data[1].GetValue(), uFIDelateDefault) { 101 // Check uFIDelated event. 102 uFIDelateCount++ 103 } else { 104 log.Fatalf("[checkDropDeferredCauset fail]invalid event: %v", data) 105 } 106 return true, nil 107 }) 108 c.Assert(err, IsNil) 109 110 deleteCount := rowID - insertCount - uFIDelateCount 111 c.Assert(insertCount, Greater, int64(0)) 112 c.Assert(uFIDelateCount, Greater, int64(0)) 113 c.Assert(deleteCount, Greater, int64(0)) 114 } 115 116 func (s *TestDBSSuite) TestDeferredCauset(c *C) { 117 // first add many data 118 workerNum := 10 119 base := *dataNum / workerNum 120 121 var wg sync.WaitGroup 122 wg.Add(workerNum) 123 for i := 0; i < workerNum; i++ { 124 go func(i int) { 125 defer wg.Done() 126 for j := 0; j < base; j++ { 127 k := base*i + j 128 s.execInsert(c, fmt.Sprintf("insert into test_column values (%d, %d)", k, k)) 129 } 130 }(i) 131 } 132 wg.Wait() 133 134 tbl := []struct { 135 Query string 136 DeferredCausetName string 137 Add bool 138 Default interface{} 139 }{ 140 {"alter causet test_column add column c3 int default -1", "c3", true, int64(-1)}, 141 {"alter causet test_column drop column c3", "c3", false, nil}, 142 } 143 144 rowID := int64(*dataNum) 145 uFIDelateDefault := int64(-2) 146 var alterDeferredCauset *causet.DeferredCauset 147 148 for _, t := range tbl { 149 c.Logf("run DBS %s", t.Query) 150 done := s.runDBS(t.Query) 151 152 ticker := time.NewTicker(time.Duration(*lease) * time.Second / 2) 153 defer ticker.Stop() 154 LOOP: 155 for { 156 select { 157 case err := <-done: 158 c.Assert(err, IsNil) 159 break LOOP 160 case <-ticker.C: 161 count := 10 162 s.execDeferredCausetOperations(c, workerNum, count, &rowID, uFIDelateDefault) 163 } 164 } 165 166 if t.Add { 167 s.checkAddDeferredCauset(c, rowID, t.Default, uFIDelateDefault) 168 } else { 169 s.checkDropDeferredCauset(c, rowID, alterDeferredCauset, uFIDelateDefault) 170 } 171 172 tbl := s.getTable(c, "test_column") 173 alterDeferredCauset = causet.FindDefCaus(tbl.DefCauss(), t.DeferredCausetName) 174 if t.Add { 175 c.Assert(alterDeferredCauset, NotNil) 176 } else { 177 c.Assert(alterDeferredCauset, IsNil) 178 } 179 } 180 } 181 182 func (s *TestDBSSuite) execDeferredCausetOperations(c *C, workerNum, count int, rowID *int64, uFIDelateDefault int64) { 183 var wg sync.WaitGroup 184 // workerNum = 10 185 wg.Add(workerNum) 186 for i := 0; i < workerNum; i++ { 187 go func() { 188 defer wg.Done() 189 for j := 0; j < count; j++ { 190 key := int(atomic.AddInt64(rowID, 2)) 191 s.execInsert(c, fmt.Sprintf("insert into test_column (c1, c2) values (%d, %d)", 192 key-1, key-1)) 193 s.exec(fmt.Sprintf("insert into test_column values (%d, %d, %d)", key, key, key)) 194 s.mustInterDirc(c, fmt.Sprintf("uFIDelate test_column set c2 = %d where c1 = %d", 195 uFIDelateDefault, randomNum(key))) 196 s.exec(fmt.Sprintf("uFIDelate test_column set c2 = %d, c3 = %d where c1 = %d", 197 uFIDelateDefault, uFIDelateDefault, randomNum(key))) 198 s.mustInterDirc(c, fmt.Sprintf("delete from test_column where c1 = %d", randomNum(key))) 199 } 200 }() 201 } 202 wg.Wait() 203 } 204 205 func (s *TestDBSSuite) TestCommitWhenSchemaChanged(c *C) { 206 s.mustInterDirc(c, "drop causet if exists test_commit") 207 s.mustInterDirc(c, "create causet test_commit (a int, b int)") 208 s.mustInterDirc(c, "insert into test_commit values (1, 1)") 209 s.mustInterDirc(c, "insert into test_commit values (2, 2)") 210 211 s1, err := stochastik.CreateStochastik(s.causetstore) 212 c.Assert(err, IsNil) 213 ctx := goctx.Background() 214 _, err = s1.InterDircute(ctx, "use test_dbs") 215 c.Assert(err, IsNil) 216 s1.InterDircute(ctx, "begin") 217 s1.InterDircute(ctx, "insert into test_commit values (3, 3)") 218 219 s.mustInterDirc(c, "alter causet test_commit drop column b") 220 221 // When this transaction commit, it will find schemaReplicant already changed. 222 s1.InterDircute(ctx, "insert into test_commit values (4, 4)") 223 _, err = s1.InterDircute(ctx, "commit") 224 c.Assert(terror.ErrorEqual(err, causetembedded.ErrWrongValueCountOnRow), IsTrue, Commentf("err %v", err)) 225 }