github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/tests/dailytest/job.go (about) 1 // Copyright 2020 PingCAP, 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 dailytest 15 16 import ( 17 "database/sql" 18 "fmt" 19 20 "github.com/pingcap/errors" 21 "github.com/pingcap/log" 22 "github.com/pingcap/parser/mysql" 23 "github.com/pingcap/tidb/types" 24 ) 25 26 func addJobs(jobCount int, jobChan chan struct{}) { 27 for i := 0; i < jobCount; i++ { 28 jobChan <- struct{}{} 29 } 30 31 close(jobChan) 32 } 33 34 func doSqls(table *table, db *sql.DB, count int) { 35 var sqls []string 36 var args [][]interface{} 37 var err error 38 39 sql, arg, err := genDeleteSqls(table, db, count/10) 40 if err != nil { 41 log.S().Error(errors.ErrorStack(err)) 42 } else { 43 sqls = append(sqls, sql...) 44 args = append(args, arg...) 45 } 46 47 sql, arg, err = genInsertSqls(table, count) 48 if err != nil { 49 log.S().Error(errors.ErrorStack(err)) 50 } else { 51 sqls = append(sqls, sql...) 52 args = append(args, arg...) 53 } 54 55 sql, arg, err = genUpdateSqls(table, db, count/10) 56 if err != nil { 57 log.S().Error(errors.ErrorStack(err)) 58 } else { 59 sqls = append(sqls, sql...) 60 args = append(args, arg...) 61 } 62 63 execSqls(db, sqls, args) 64 } 65 66 func execSqls(db *sql.DB, sqls []string, args [][]interface{}) { 67 txn, err := db.Begin() 68 if err != nil { 69 log.S().Fatalf(errors.ErrorStack(err)) 70 } 71 72 for i := range sqls { 73 _, err = txn.Exec(sqls[i], args[i]...) 74 if err != nil { 75 log.S().Error(errors.ErrorStack(err)) 76 } 77 } 78 79 err = txn.Commit() 80 if err != nil { 81 log.S().Warn(errors.ErrorStack(err)) 82 } 83 } 84 85 func doJob(table *table, db *sql.DB, batch int, jobChan chan struct{}, doneChan chan struct{}) { 86 count := 0 87 for range jobChan { 88 count++ 89 if count == batch { 90 doSqls(table, db, count) 91 count = 0 92 } 93 } 94 95 if count > 0 { 96 doSqls(table, db, count) 97 } 98 99 doneChan <- struct{}{} 100 } 101 102 func doWait(doneChan chan struct{}, workerCount int) { 103 for i := 0; i < workerCount; i++ { 104 <-doneChan 105 } 106 107 close(doneChan) 108 } 109 110 func doDMLProcess(table *table, db *sql.DB, jobCount int, workerCount int, batch int) { 111 jobChan := make(chan struct{}, 16*workerCount) 112 doneChan := make(chan struct{}, workerCount) 113 114 go addJobs(jobCount, jobChan) 115 116 for i := 0; i < workerCount; i++ { 117 go doJob(table, db, batch, jobChan, doneChan) 118 } 119 120 doWait(doneChan, workerCount) 121 } 122 123 func doDDLProcess(table *table, db *sql.DB) { 124 // do drop column ddl 125 index := randInt(2, len(table.columns)-1) 126 col := table.columns[index] 127 128 _, ok1 := table.indices[col.name] 129 _, ok2 := table.uniqIndices[col.name] 130 if !ok1 && !ok2 { 131 newCols := make([]*column, 0, len(table.columns)-1) 132 newCols = append(newCols, table.columns[:index]...) 133 newCols = append(newCols, table.columns[index+1:]...) 134 table.columns = newCols 135 sql := fmt.Sprintf("alter table %s drop column %s", table.name, col.name) 136 execSqls(db, []string{sql}, [][]interface{}{{}}) 137 } 138 139 // do add column ddl 140 index = randInt(2, len(table.columns)-1) 141 colName := randString(5) 142 143 col = &column{ 144 name: colName, 145 tp: &types.FieldType{ 146 Tp: mysql.TypeVarchar, 147 Flen: 45, 148 }, 149 } 150 151 newCols := make([]*column, 0, len(table.columns)+1) 152 newCols = append(newCols, table.columns[:index]...) 153 newCols = append(newCols, col) 154 newCols = append(newCols, table.columns[index:]...) 155 156 table.columns = newCols 157 sql := fmt.Sprintf("alter table %s add column `%s` varchar(45) after %s", table.name, col.name, table.columns[index-1].name) 158 execSqls(db, []string{sql}, [][]interface{}{{}}) 159 } 160 161 func doProcess(table *table, db *sql.DB, jobCount int, workerCount int, batch int) { 162 if len(table.columns) <= 2 { 163 log.S().Fatal("column count must > 2, and the first and second column are for primary key") 164 } 165 166 doDMLProcess(table, db, jobCount/2, workerCount, batch) 167 doDDLProcess(table, db) 168 doDMLProcess(table, db, jobCount/2, workerCount, batch) 169 }