github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/dbs_worker_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 dbs 15 16 import ( 17 "context" 18 "sync" 19 "time" 20 21 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 22 "github.com/whtcorpsinc/BerolinaSQL/ast" 23 "github.com/whtcorpsinc/BerolinaSQL/charset" 24 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 25 "github.com/whtcorpsinc/BerolinaSQL/terror" 26 . "github.com/whtcorpsinc/check" 27 "github.com/whtcorpsinc/errors" 28 "github.com/whtcorpsinc/failpoint" 29 "github.com/whtcorpsinc/milevadb/causet" 30 "github.com/whtcorpsinc/milevadb/ekv" 31 "github.com/whtcorpsinc/milevadb/soliton/admin" 32 "github.com/whtcorpsinc/milevadb/soliton/mock" 33 "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 34 "github.com/whtcorpsinc/milevadb/soliton/sqlexec" 35 "github.com/whtcorpsinc/milevadb/spacetime" 36 "github.com/whtcorpsinc/milevadb/stochastikctx" 37 "github.com/whtcorpsinc/milevadb/types" 38 ) 39 40 var _ = Suite(&testDBSSuite{}) 41 var _ = SerialSuites(&testDBSSerialSuite{}) 42 43 type testDBSSuite struct { 44 solitonutil.CommonHandleSuite 45 } 46 type testDBSSerialSuite struct{} 47 48 const testLease = 5 * time.Millisecond 49 50 func (s *testDBSSerialSuite) SetUpSuite(c *C) { 51 SetWaitTimeWhenErrorOccurred(1 * time.Microsecond) 52 53 // We hope that this test is serially executed. So put it here. 54 s.testRunWorker(c) 55 } 56 57 func (s *testDBSSuite) TestCheckTenant(c *C) { 58 causetstore := testCreateStore(c, "test_tenant") 59 defer causetstore.Close() 60 61 d1 := testNewDBSAndStart( 62 context.Background(), 63 c, 64 WithStore(causetstore), 65 WithLease(testLease), 66 ) 67 defer d1.Stop() 68 time.Sleep(testLease) 69 testCheckTenant(c, d1, true) 70 71 c.Assert(d1.GetLease(), Equals, testLease) 72 } 73 74 // testRunWorker tests no job is handled when the value of RunWorker is false. 75 func (s *testDBSSerialSuite) testRunWorker(c *C) { 76 causetstore := testCreateStore(c, "test_run_worker") 77 defer causetstore.Close() 78 79 RunWorker = false 80 d := testNewDBSAndStart( 81 context.Background(), 82 c, 83 WithStore(causetstore), 84 WithLease(testLease), 85 ) 86 testCheckTenant(c, d, false) 87 defer d.Stop() 88 89 // Make sure the DBS worker is nil. 90 worker := d.generalWorker() 91 c.Assert(worker, IsNil) 92 // Make sure the DBS job can be done and exit that goroutine. 93 RunWorker = true 94 d1 := testNewDBSAndStart( 95 context.Background(), 96 c, 97 WithStore(causetstore), 98 WithLease(testLease), 99 ) 100 testCheckTenant(c, d1, true) 101 defer d1.Stop() 102 worker = d1.generalWorker() 103 c.Assert(worker, NotNil) 104 } 105 106 func (s *testDBSSuite) TestSchemaError(c *C) { 107 causetstore := testCreateStore(c, "test_schema_error") 108 defer causetstore.Close() 109 110 d := testNewDBSAndStart( 111 context.Background(), 112 c, 113 WithStore(causetstore), 114 WithLease(testLease), 115 ) 116 defer d.Stop() 117 ctx := testNewContext(d) 118 119 doDBSJobErr(c, 1, 0, perceptron.CausetActionCreateSchema, []interface{}{1}, ctx, d) 120 } 121 122 func (s *testDBSSuite) TestBlockError(c *C) { 123 causetstore := testCreateStore(c, "test_block_error") 124 defer causetstore.Close() 125 126 d := testNewDBSAndStart( 127 context.Background(), 128 c, 129 WithStore(causetstore), 130 WithLease(testLease), 131 ) 132 defer d.Stop() 133 ctx := testNewContext(d) 134 135 // Schema ID is wrong, so dropping causet is failed. 136 doDBSJobErr(c, -1, 1, perceptron.CausetActionDropBlock, nil, ctx, d) 137 // Block ID is wrong, so dropping causet is failed. 138 dbInfo := testSchemaInfo(c, d, "test") 139 testCreateSchema(c, testNewContext(d), d, dbInfo) 140 job := doDBSJobErr(c, dbInfo.ID, -1, perceptron.CausetActionDropBlock, nil, ctx, d) 141 142 // Block ID or schemaReplicant ID is wrong, so getting causet is failed. 143 tblInfo := testBlockInfo(c, d, "t", 3) 144 testCreateBlock(c, ctx, d, dbInfo, tblInfo) 145 err := ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 146 job.SchemaID = -1 147 job.BlockID = -1 148 t := spacetime.NewMeta(txn) 149 _, err1 := getBlockInfoAndCancelFaultJob(t, job, job.SchemaID) 150 c.Assert(err1, NotNil) 151 job.SchemaID = dbInfo.ID 152 _, err1 = getBlockInfoAndCancelFaultJob(t, job, job.SchemaID) 153 c.Assert(err1, NotNil) 154 return nil 155 }) 156 c.Assert(err, IsNil) 157 158 // Args is wrong, so creating causet is failed. 159 doDBSJobErr(c, 1, 1, perceptron.CausetActionCreateBlock, []interface{}{1}, ctx, d) 160 // Schema ID is wrong, so creating causet is failed. 161 doDBSJobErr(c, -1, tblInfo.ID, perceptron.CausetActionCreateBlock, []interface{}{tblInfo}, ctx, d) 162 // Block exists, so creating causet is failed. 163 tblInfo.ID = tblInfo.ID + 1 164 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionCreateBlock, []interface{}{tblInfo}, ctx, d) 165 166 } 167 168 func (s *testDBSSuite) TestViewError(c *C) { 169 causetstore := testCreateStore(c, "test_view_error") 170 defer causetstore.Close() 171 172 d := testNewDBSAndStart( 173 context.Background(), 174 c, 175 WithStore(causetstore), 176 WithLease(testLease), 177 ) 178 defer d.Stop() 179 ctx := testNewContext(d) 180 dbInfo := testSchemaInfo(c, d, "test") 181 testCreateSchema(c, testNewContext(d), d, dbInfo) 182 183 // Block ID or schemaReplicant ID is wrong, so getting causet is failed. 184 tblInfo := testViewInfo(c, d, "t", 3) 185 testCreateView(c, ctx, d, dbInfo, tblInfo) 186 187 // Args is wrong, so creating view is failed. 188 doDBSJobErr(c, 1, 1, perceptron.CausetActionCreateView, []interface{}{1}, ctx, d) 189 // Schema ID is wrong and orReplace is false, so creating view is failed. 190 doDBSJobErr(c, -1, tblInfo.ID, perceptron.CausetActionCreateView, []interface{}{tblInfo, false}, ctx, d) 191 // View exists and orReplace is false, so creating view is failed. 192 tblInfo.ID = tblInfo.ID + 1 193 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionCreateView, []interface{}{tblInfo, false}, ctx, d) 194 195 } 196 197 func (s *testDBSSuite) TestInvalidDBSJob(c *C) { 198 causetstore := testCreateStore(c, "test_invalid_dbs_job_type_error") 199 defer causetstore.Close() 200 d := testNewDBSAndStart( 201 context.Background(), 202 c, 203 WithStore(causetstore), 204 WithLease(testLease), 205 ) 206 defer d.Stop() 207 ctx := testNewContext(d) 208 209 job := &perceptron.Job{ 210 SchemaID: 0, 211 BlockID: 0, 212 Type: perceptron.CausetActionNone, 213 BinlogInfo: &perceptron.HistoryInfo{}, 214 Args: []interface{}{}, 215 } 216 err := d.doDBSJob(ctx, job) 217 c.Assert(err.Error(), Equals, "[dbs:8204]invalid dbs job type: none") 218 } 219 220 func (s *testDBSSuite) TestForeignKeyError(c *C) { 221 causetstore := testCreateStore(c, "test_foreign_key_error") 222 defer causetstore.Close() 223 224 d := testNewDBSAndStart( 225 context.Background(), 226 c, 227 WithStore(causetstore), 228 WithLease(testLease), 229 ) 230 defer d.Stop() 231 ctx := testNewContext(d) 232 233 doDBSJobErr(c, -1, 1, perceptron.CausetActionAddForeignKey, nil, ctx, d) 234 doDBSJobErr(c, -1, 1, perceptron.CausetActionDropForeignKey, nil, ctx, d) 235 236 dbInfo := testSchemaInfo(c, d, "test") 237 tblInfo := testBlockInfo(c, d, "t", 3) 238 testCreateSchema(c, ctx, d, dbInfo) 239 testCreateBlock(c, ctx, d, dbInfo, tblInfo) 240 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionDropForeignKey, []interface{}{perceptron.NewCIStr("c1_foreign_key")}, ctx, d) 241 } 242 243 func (s *testDBSSuite) TestIndexError(c *C) { 244 causetstore := testCreateStore(c, "test_index_error") 245 defer causetstore.Close() 246 247 d := testNewDBSAndStart( 248 context.Background(), 249 c, 250 WithStore(causetstore), 251 WithLease(testLease), 252 ) 253 defer d.Stop() 254 ctx := testNewContext(d) 255 256 // Schema ID is wrong. 257 doDBSJobErr(c, -1, 1, perceptron.CausetActionAddIndex, nil, ctx, d) 258 doDBSJobErr(c, -1, 1, perceptron.CausetActionDropIndex, nil, ctx, d) 259 260 dbInfo := testSchemaInfo(c, d, "test") 261 tblInfo := testBlockInfo(c, d, "t", 3) 262 testCreateSchema(c, ctx, d, dbInfo) 263 testCreateBlock(c, ctx, d, dbInfo, tblInfo) 264 265 // for adding index 266 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddIndex, []interface{}{1}, ctx, d) 267 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddIndex, 268 []interface{}{false, perceptron.NewCIStr("t"), 1, 269 []*ast.IndexPartSpecification{{DeferredCauset: &ast.DeferredCausetName{Name: perceptron.NewCIStr("c")}, Length: 256}}}, ctx, d) 270 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddIndex, 271 []interface{}{false, perceptron.NewCIStr("c1_index"), 1, 272 []*ast.IndexPartSpecification{{DeferredCauset: &ast.DeferredCausetName{Name: perceptron.NewCIStr("c")}, Length: 256}}}, ctx, d) 273 testCreateIndex(c, ctx, d, dbInfo, tblInfo, false, "c1_index", "c1") 274 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddIndex, 275 []interface{}{false, perceptron.NewCIStr("c1_index"), 1, 276 []*ast.IndexPartSpecification{{DeferredCauset: &ast.DeferredCausetName{Name: perceptron.NewCIStr("c1")}, Length: 256}}}, ctx, d) 277 278 // for dropping index 279 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionDropIndex, []interface{}{1}, ctx, d) 280 testDropIndex(c, ctx, d, dbInfo, tblInfo, "c1_index") 281 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionDropIndex, []interface{}{perceptron.NewCIStr("c1_index")}, ctx, d) 282 } 283 284 func (s *testDBSSuite) TestDeferredCausetError(c *C) { 285 causetstore := testCreateStore(c, "test_defCausumn_error") 286 defer causetstore.Close() 287 d := testNewDBSAndStart( 288 context.Background(), 289 c, 290 WithStore(causetstore), 291 WithLease(testLease), 292 ) 293 defer d.Stop() 294 ctx := testNewContext(d) 295 296 dbInfo := testSchemaInfo(c, d, "test") 297 tblInfo := testBlockInfo(c, d, "t", 3) 298 testCreateSchema(c, ctx, d, dbInfo) 299 testCreateBlock(c, ctx, d, dbInfo, tblInfo) 300 defCaus := &perceptron.DeferredCausetInfo{ 301 Name: perceptron.NewCIStr("c4"), 302 Offset: len(tblInfo.DeferredCausets), 303 DefaultValue: 0, 304 } 305 defCaus.ID = allocateDeferredCausetID(tblInfo) 306 defCaus.FieldType = *types.NewFieldType(allegrosql.TypeLong) 307 pos := &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionAfter, RelativeDeferredCauset: &ast.DeferredCausetName{Name: perceptron.NewCIStr("c5")}} 308 309 defcaus := &[]*perceptron.DeferredCausetInfo{defCaus} 310 positions := &[]*ast.DeferredCausetPosition{pos} 311 312 // for adding defCausumn 313 doDBSJobErr(c, -1, tblInfo.ID, perceptron.CausetActionAddDeferredCauset, []interface{}{defCaus, pos, 0}, ctx, d) 314 doDBSJobErr(c, dbInfo.ID, -1, perceptron.CausetActionAddDeferredCauset, []interface{}{defCaus, pos, 0}, ctx, d) 315 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCauset, []interface{}{0}, ctx, d) 316 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCauset, []interface{}{defCaus, pos, 0}, ctx, d) 317 318 // for dropping defCausumn 319 doDBSJobErr(c, -1, tblInfo.ID, perceptron.CausetActionDropDeferredCauset, []interface{}{defCaus, pos, 0}, ctx, d) 320 doDBSJobErr(c, dbInfo.ID, -1, perceptron.CausetActionDropDeferredCauset, []interface{}{defCaus, pos, 0}, ctx, d) 321 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionDropDeferredCauset, []interface{}{0}, ctx, d) 322 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionDropDeferredCauset, []interface{}{perceptron.NewCIStr("c5")}, ctx, d) 323 324 // for adding defCausumns 325 doDBSJobErr(c, -1, tblInfo.ID, perceptron.CausetActionAddDeferredCausets, []interface{}{defcaus, positions, 0}, ctx, d) 326 doDBSJobErr(c, dbInfo.ID, -1, perceptron.CausetActionAddDeferredCausets, []interface{}{defcaus, positions, 0}, ctx, d) 327 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCausets, []interface{}{0}, ctx, d) 328 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCausets, []interface{}{defcaus, positions, 0}, ctx, d) 329 330 // for dropping defCausumns 331 doDBSJobErr(c, -1, tblInfo.ID, perceptron.CausetActionDropDeferredCausets, []interface{}{defCaus, pos, 0}, ctx, d) 332 doDBSJobErr(c, dbInfo.ID, -1, perceptron.CausetActionDropDeferredCausets, []interface{}{defCaus, pos, 0}, ctx, d) 333 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionDropDeferredCausets, []interface{}{0}, ctx, d) 334 doDBSJobErr(c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionDropDeferredCausets, []interface{}{[]perceptron.CIStr{perceptron.NewCIStr("c5"), perceptron.NewCIStr("c6")}, make([]bool, 2)}, ctx, d) 335 } 336 337 func testCheckTenant(c *C, d *dbs, expectedVal bool) { 338 c.Assert(d.isTenant(), Equals, expectedVal) 339 } 340 341 func testCheckJobDone(c *C, d *dbs, job *perceptron.Job, isAdd bool) { 342 ekv.RunInNewTxn(d.causetstore, false, func(txn ekv.Transaction) error { 343 t := spacetime.NewMeta(txn) 344 historyJob, err := t.GetHistoryDBSJob(job.ID) 345 c.Assert(err, IsNil) 346 checkHistoryJob(c, historyJob) 347 if isAdd { 348 c.Assert(historyJob.SchemaState, Equals, perceptron.StatePublic) 349 } else { 350 c.Assert(historyJob.SchemaState, Equals, perceptron.StateNone) 351 } 352 353 return nil 354 }) 355 } 356 357 func testCheckJobCancelled(c *C, d *dbs, job *perceptron.Job, state *perceptron.SchemaState) { 358 ekv.RunInNewTxn(d.causetstore, false, func(txn ekv.Transaction) error { 359 t := spacetime.NewMeta(txn) 360 historyJob, err := t.GetHistoryDBSJob(job.ID) 361 c.Assert(err, IsNil) 362 c.Assert(historyJob.IsCancelled() || historyJob.IsRollbackDone(), IsTrue, Commentf("history job %s", historyJob)) 363 if state != nil { 364 c.Assert(historyJob.SchemaState, Equals, *state) 365 } 366 return nil 367 }) 368 } 369 370 func doDBSJobErrWithSchemaState(ctx stochastikctx.Context, d *dbs, c *C, schemaID, blockID int64, tp perceptron.CausetActionType, 371 args []interface{}, state *perceptron.SchemaState) *perceptron.Job { 372 job := &perceptron.Job{ 373 SchemaID: schemaID, 374 BlockID: blockID, 375 Type: tp, 376 Args: args, 377 BinlogInfo: &perceptron.HistoryInfo{}, 378 } 379 err := d.doDBSJob(ctx, job) 380 // TODO: Add the detail error check. 381 c.Assert(err, NotNil, Commentf("err:%v", err)) 382 testCheckJobCancelled(c, d, job, state) 383 384 return job 385 } 386 387 func doDBSJobSuccess(ctx stochastikctx.Context, d *dbs, c *C, schemaID, blockID int64, tp perceptron.CausetActionType, 388 args []interface{}) { 389 job := &perceptron.Job{ 390 SchemaID: schemaID, 391 BlockID: blockID, 392 Type: tp, 393 Args: args, 394 BinlogInfo: &perceptron.HistoryInfo{}, 395 } 396 err := d.doDBSJob(ctx, job) 397 c.Assert(err, IsNil) 398 } 399 400 func doDBSJobErr(c *C, schemaID, blockID int64, tp perceptron.CausetActionType, args []interface{}, 401 ctx stochastikctx.Context, d *dbs) *perceptron.Job { 402 return doDBSJobErrWithSchemaState(ctx, d, c, schemaID, blockID, tp, args, nil) 403 } 404 405 func checkCancelState(txn ekv.Transaction, job *perceptron.Job, test *testCancelJob) error { 406 var checkErr error 407 addIndexFirstReorg := (test.act == perceptron.CausetActionAddIndex || test.act == perceptron.CausetActionAddPrimaryKey) && 408 job.SchemaState == perceptron.StateWriteReorganization && job.SnapshotVer == 0 409 // If the action is adding index and the state is writing reorganization, it wants to test the case of cancelling the job when backfilling indexes. 410 // When the job satisfies this case of addIndexFirstReorg, the worker hasn't started to backfill indexes. 411 if test.cancelState == job.SchemaState && !addIndexFirstReorg && !job.IsRollingback() { 412 errs, err := admin.CancelJobs(txn, test.jobIDs) 413 if err != nil { 414 checkErr = errors.Trace(err) 415 return checkErr 416 } 417 // It only tests cancel one DBS job. 418 if !terror.ErrorEqual(errs[0], test.cancelRetErrs[0]) { 419 checkErr = errors.Trace(errs[0]) 420 return checkErr 421 } 422 } 423 return checkErr 424 } 425 426 type testCancelJob struct { 427 jobIDs []int64 428 cancelRetErrs []error // cancelRetErrs is the first return value of CancelJobs. 429 act perceptron.CausetActionType // act is the job action. 430 cancelState perceptron.SchemaState 431 } 432 433 func buildCancelJobTests(firstID int64) []testCancelJob { 434 noErrs := []error{nil} 435 tests := []testCancelJob{ 436 {act: perceptron.CausetActionAddIndex, jobIDs: []int64{firstID + 1}, cancelRetErrs: noErrs, cancelState: perceptron.StateDeleteOnly}, 437 {act: perceptron.CausetActionAddIndex, jobIDs: []int64{firstID + 2}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteOnly}, 438 {act: perceptron.CausetActionAddIndex, jobIDs: []int64{firstID + 3}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteReorganization}, 439 {act: perceptron.CausetActionAddIndex, jobIDs: []int64{firstID + 4}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 4)}, cancelState: perceptron.StatePublic}, 440 441 // Test cancel drop index job , see TestCancelDropIndex. 442 {act: perceptron.CausetActionAddDeferredCauset, jobIDs: []int64{firstID + 5}, cancelRetErrs: noErrs, cancelState: perceptron.StateDeleteOnly}, 443 {act: perceptron.CausetActionAddDeferredCauset, jobIDs: []int64{firstID + 6}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteOnly}, 444 {act: perceptron.CausetActionAddDeferredCauset, jobIDs: []int64{firstID + 7}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteReorganization}, 445 {act: perceptron.CausetActionAddDeferredCauset, jobIDs: []int64{firstID + 8}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 8)}, cancelState: perceptron.StatePublic}, 446 447 // Test create causet, watch out, causet id will alloc a globalID. 448 {act: perceptron.CausetActionCreateBlock, jobIDs: []int64{firstID + 10}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 449 // Test create database, watch out, database id will alloc a globalID. 450 {act: perceptron.CausetActionCreateSchema, jobIDs: []int64{firstID + 12}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 451 452 {act: perceptron.CausetActionDropDeferredCauset, jobIDs: []int64{firstID + 13}, cancelRetErrs: []error{admin.ErrCannotCancelDBSJob.GenWithStackByArgs(firstID + 13)}, cancelState: perceptron.StateDeleteOnly}, 453 {act: perceptron.CausetActionDropDeferredCauset, jobIDs: []int64{firstID + 14}, cancelRetErrs: []error{admin.ErrCannotCancelDBSJob.GenWithStackByArgs(firstID + 14)}, cancelState: perceptron.StateWriteOnly}, 454 {act: perceptron.CausetActionDropDeferredCauset, jobIDs: []int64{firstID + 15}, cancelRetErrs: []error{admin.ErrCannotCancelDBSJob.GenWithStackByArgs(firstID + 15)}, cancelState: perceptron.StateWriteReorganization}, 455 {act: perceptron.CausetActionRebaseAutoID, jobIDs: []int64{firstID + 16}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 456 {act: perceptron.CausetActionShardRowID, jobIDs: []int64{firstID + 17}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 457 458 {act: perceptron.CausetActionModifyDeferredCauset, jobIDs: []int64{firstID + 18}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 459 {act: perceptron.CausetActionModifyDeferredCauset, jobIDs: []int64{firstID + 19}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 19)}, cancelState: perceptron.StateDeleteOnly}, 460 461 {act: perceptron.CausetActionAddForeignKey, jobIDs: []int64{firstID + 20}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 462 {act: perceptron.CausetActionAddForeignKey, jobIDs: []int64{firstID + 21}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 21)}, cancelState: perceptron.StatePublic}, 463 {act: perceptron.CausetActionDropForeignKey, jobIDs: []int64{firstID + 22}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 464 {act: perceptron.CausetActionDropForeignKey, jobIDs: []int64{firstID + 23}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 23)}, cancelState: perceptron.StatePublic}, 465 466 {act: perceptron.CausetActionRenameBlock, jobIDs: []int64{firstID + 24}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 467 {act: perceptron.CausetActionRenameBlock, jobIDs: []int64{firstID + 25}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 25)}, cancelState: perceptron.StatePublic}, 468 469 {act: perceptron.CausetActionModifyBlockCharsetAndDefCauslate, jobIDs: []int64{firstID + 26}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 470 {act: perceptron.CausetActionModifyBlockCharsetAndDefCauslate, jobIDs: []int64{firstID + 27}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 27)}, cancelState: perceptron.StatePublic}, 471 {act: perceptron.CausetActionTruncateBlockPartition, jobIDs: []int64{firstID + 28}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 472 {act: perceptron.CausetActionTruncateBlockPartition, jobIDs: []int64{firstID + 29}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 29)}, cancelState: perceptron.StatePublic}, 473 {act: perceptron.CausetActionModifySchemaCharsetAndDefCauslate, jobIDs: []int64{firstID + 31}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 474 {act: perceptron.CausetActionModifySchemaCharsetAndDefCauslate, jobIDs: []int64{firstID + 32}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 32)}, cancelState: perceptron.StatePublic}, 475 476 {act: perceptron.CausetActionAddPrimaryKey, jobIDs: []int64{firstID + 33}, cancelRetErrs: noErrs, cancelState: perceptron.StateDeleteOnly}, 477 {act: perceptron.CausetActionAddPrimaryKey, jobIDs: []int64{firstID + 34}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteOnly}, 478 {act: perceptron.CausetActionAddPrimaryKey, jobIDs: []int64{firstID + 35}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteReorganization}, 479 {act: perceptron.CausetActionAddPrimaryKey, jobIDs: []int64{firstID + 36}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 36)}, cancelState: perceptron.StatePublic}, 480 {act: perceptron.CausetActionDropPrimaryKey, jobIDs: []int64{firstID + 37}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteOnly}, 481 {act: perceptron.CausetActionDropPrimaryKey, jobIDs: []int64{firstID + 38}, cancelRetErrs: []error{admin.ErrCannotCancelDBSJob.GenWithStackByArgs(firstID + 38)}, cancelState: perceptron.StateDeleteOnly}, 482 483 {act: perceptron.CausetActionAddDeferredCausets, jobIDs: []int64{firstID + 39}, cancelRetErrs: noErrs, cancelState: perceptron.StateDeleteOnly}, 484 {act: perceptron.CausetActionAddDeferredCausets, jobIDs: []int64{firstID + 40}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteOnly}, 485 {act: perceptron.CausetActionAddDeferredCausets, jobIDs: []int64{firstID + 41}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteReorganization}, 486 {act: perceptron.CausetActionAddDeferredCausets, jobIDs: []int64{firstID + 42}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 42)}, cancelState: perceptron.StatePublic}, 487 488 {act: perceptron.CausetActionDropDeferredCausets, jobIDs: []int64{firstID + 43}, cancelRetErrs: []error{admin.ErrCannotCancelDBSJob.GenWithStackByArgs(firstID + 43)}, cancelState: perceptron.StateDeleteOnly}, 489 {act: perceptron.CausetActionDropDeferredCausets, jobIDs: []int64{firstID + 44}, cancelRetErrs: []error{admin.ErrCannotCancelDBSJob.GenWithStackByArgs(firstID + 44)}, cancelState: perceptron.StateWriteOnly}, 490 {act: perceptron.CausetActionDropDeferredCausets, jobIDs: []int64{firstID + 45}, cancelRetErrs: []error{admin.ErrCannotCancelDBSJob.GenWithStackByArgs(firstID + 45)}, cancelState: perceptron.StateWriteReorganization}, 491 492 {act: perceptron.CausetActionAlterIndexVisibility, jobIDs: []int64{firstID + 47}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 493 {act: perceptron.CausetActionAlterIndexVisibility, jobIDs: []int64{firstID + 48}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 48)}, cancelState: perceptron.StatePublic}, 494 495 {act: perceptron.CausetActionExchangeBlockPartition, jobIDs: []int64{firstID + 54}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 496 {act: perceptron.CausetActionExchangeBlockPartition, jobIDs: []int64{firstID + 55}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob.GenWithStackByArgs(firstID + 55)}, cancelState: perceptron.StatePublic}, 497 498 {act: perceptron.CausetActionAddBlockPartition, jobIDs: []int64{firstID + 60}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 499 {act: perceptron.CausetActionAddBlockPartition, jobIDs: []int64{firstID + 61}, cancelRetErrs: noErrs, cancelState: perceptron.StateReplicaOnly}, 500 {act: perceptron.CausetActionAddBlockPartition, jobIDs: []int64{firstID + 62}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob}, cancelState: perceptron.StatePublic}, 501 502 // modify defCausumn has two different types, normal-type and reorg-type. The latter has 5 states and it can be cancelled except the public state. 503 {act: perceptron.CausetActionModifyDeferredCauset, jobIDs: []int64{firstID + 65}, cancelRetErrs: noErrs, cancelState: perceptron.StateNone}, 504 {act: perceptron.CausetActionModifyDeferredCauset, jobIDs: []int64{firstID + 66}, cancelRetErrs: noErrs, cancelState: perceptron.StateDeleteOnly}, 505 {act: perceptron.CausetActionModifyDeferredCauset, jobIDs: []int64{firstID + 67}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteOnly}, 506 {act: perceptron.CausetActionModifyDeferredCauset, jobIDs: []int64{firstID + 68}, cancelRetErrs: noErrs, cancelState: perceptron.StateWriteReorganization}, 507 {act: perceptron.CausetActionModifyDeferredCauset, jobIDs: []int64{firstID + 69}, cancelRetErrs: []error{admin.ErrCancelFinishedDBSJob}, cancelState: perceptron.StatePublic}, 508 } 509 510 return tests 511 } 512 513 func (s *testDBSSerialSuite) checkDropIdx(c *C, d *dbs, schemaID int64, blockID int64, idxName string, success bool) { 514 checkIdxExist(c, d, schemaID, blockID, idxName, !success) 515 } 516 517 func (s *testDBSSerialSuite) checkAddIdx(c *C, d *dbs, schemaID int64, blockID int64, idxName string, success bool) { 518 checkIdxExist(c, d, schemaID, blockID, idxName, success) 519 } 520 521 func checkIdxExist(c *C, d *dbs, schemaID int64, blockID int64, idxName string, expectedExist bool) { 522 changedBlock := testGetBlock(c, d, schemaID, blockID) 523 var found bool 524 for _, idxInfo := range changedBlock.Meta().Indices { 525 if idxInfo.Name.O == idxName { 526 found = true 527 break 528 } 529 } 530 c.Assert(found, Equals, expectedExist) 531 } 532 533 func (s *testDBSSerialSuite) checkAddDeferredCausets(c *C, d *dbs, schemaID int64, blockID int64, defCausNames []string, success bool) { 534 changedBlock := testGetBlock(c, d, schemaID, blockID) 535 found := !checkDeferredCausetsNotFound(changedBlock, defCausNames) 536 c.Assert(found, Equals, success) 537 } 538 539 func (s *testDBSSerialSuite) checkCancelDropDeferredCausets(c *C, d *dbs, schemaID int64, blockID int64, defCausNames []string, success bool) { 540 changedBlock := testGetBlock(c, d, schemaID, blockID) 541 notFound := checkDeferredCausetsNotFound(changedBlock, defCausNames) 542 c.Assert(notFound, Equals, success) 543 } 544 545 func checkDeferredCausetsNotFound(t causet.Block, defCausNames []string) bool { 546 notFound := true 547 for _, defCausName := range defCausNames { 548 for _, defCausInfo := range t.Meta().DeferredCausets { 549 if defCausInfo.Name.O == defCausName { 550 notFound = false 551 } 552 } 553 } 554 return notFound 555 } 556 557 func checkIdxVisibility(changedBlock causet.Block, idxName string, expected bool) bool { 558 for _, idxInfo := range changedBlock.Meta().Indices { 559 if idxInfo.Name.O == idxName && idxInfo.Invisible == expected { 560 return true 561 } 562 } 563 return false 564 } 565 566 func (s *testDBSSerialSuite) TestCancelJob(c *C) { 567 causetstore := testCreateStore(c, "test_cancel_job") 568 defer causetstore.Close() 569 d := testNewDBSAndStart( 570 context.Background(), 571 c, 572 WithStore(causetstore), 573 WithLease(testLease), 574 ) 575 defer d.Stop() 576 dbInfo := testSchemaInfo(c, d, "test_cancel_job") 577 testCreateSchema(c, testNewContext(d), d, dbInfo) 578 // create a partition causet. 579 partitionTblInfo := testBlockInfoWithPartition(c, d, "t_partition", 5) 580 // Skip using sessPool. Make sure adding primary key can be successful. 581 partitionTblInfo.DeferredCausets[0].Flag |= allegrosql.NotNullFlag 582 // create causet t (c1 int, c2 int, c3 int, c4 int, c5 int); 583 tblInfo := testBlockInfo(c, d, "t", 5) 584 ctx := testNewContext(d) 585 err := ctx.NewTxn(context.Background()) 586 c.Assert(err, IsNil) 587 testCreateBlock(c, ctx, d, dbInfo, partitionTblInfo) 588 blockAutoID := int64(100) 589 shardRowIDBits := uint64(5) 590 tblInfo.AutoIncID = blockAutoID 591 tblInfo.ShardRowIDBits = shardRowIDBits 592 job := testCreateBlock(c, ctx, d, dbInfo, tblInfo) 593 // insert t values (1, 2, 3, 4, 5); 594 originBlock := testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 595 event := types.MakeCausets(1, 2, 3, 4, 5) 596 _, err = originBlock.AddRecord(ctx, event) 597 c.Assert(err, IsNil) 598 txn, err := ctx.Txn(true) 599 c.Assert(err, IsNil) 600 err = txn.Commit(context.Background()) 601 c.Assert(err, IsNil) 602 603 tc := &TestDBSCallback{} 604 // set up hook 605 firstJobID := job.ID 606 tests := buildCancelJobTests(firstJobID) 607 var checkErr error 608 var mu sync.Mutex 609 var test *testCancelJob 610 uFIDelateTest := func(t *testCancelJob) { 611 mu.Lock() 612 test = t 613 mu.Unlock() 614 } 615 hookCancelFunc := func(job *perceptron.Job) { 616 if job.State == perceptron.JobStateSynced || job.State == perceptron.JobStateCancelled || job.State == perceptron.JobStateCancelling { 617 return 618 } 619 // This hook only valid for the related test job. 620 // This is use to avoid parallel test fail. 621 mu.Lock() 622 if len(test.jobIDs) > 0 && test.jobIDs[0] != job.ID { 623 mu.Unlock() 624 return 625 } 626 mu.Unlock() 627 if checkErr != nil { 628 return 629 } 630 631 hookCtx := mock.NewContext() 632 hookCtx.CausetStore = causetstore 633 err1 := hookCtx.NewTxn(context.Background()) 634 if err1 != nil { 635 checkErr = errors.Trace(err1) 636 return 637 } 638 txn, err1 = hookCtx.Txn(true) 639 if err1 != nil { 640 checkErr = errors.Trace(err1) 641 return 642 } 643 mu.Lock() 644 checkErr = checkCancelState(txn, job, test) 645 mu.Unlock() 646 if checkErr != nil { 647 return 648 } 649 err1 = txn.Commit(context.Background()) 650 if err1 != nil { 651 checkErr = errors.Trace(err1) 652 return 653 } 654 } 655 tc.onJobUFIDelated = hookCancelFunc 656 tc.onJobRunBefore = hookCancelFunc 657 d.SetHook(tc) 658 659 // for adding index 660 uFIDelateTest(&tests[0]) 661 idxOrigName := "idx" 662 validArgs := []interface{}{false, perceptron.NewCIStr(idxOrigName), 663 []*ast.IndexPartSpecification{{ 664 DeferredCauset: &ast.DeferredCausetName{Name: perceptron.NewCIStr("c1")}, 665 Length: -1, 666 }}, nil} 667 668 // When the job satisfies this test case, the option will be rollback, so the job's schemaReplicant state is none. 669 cancelState := perceptron.StateNone 670 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddIndex, validArgs, &cancelState) 671 c.Check(errors.ErrorStack(checkErr), Equals, "") 672 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, false) 673 uFIDelateTest(&tests[1]) 674 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddIndex, validArgs, &cancelState) 675 c.Check(errors.ErrorStack(checkErr), Equals, "") 676 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, false) 677 uFIDelateTest(&tests[2]) 678 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddIndex, validArgs, &cancelState) 679 c.Check(errors.ErrorStack(checkErr), Equals, "") 680 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, false) 681 uFIDelateTest(&tests[3]) 682 testCreateIndex(c, ctx, d, dbInfo, tblInfo, false, "idx", "c2") 683 c.Check(errors.ErrorStack(checkErr), Equals, "") 684 txn, err = ctx.Txn(true) 685 c.Assert(err, IsNil) 686 c.Assert(txn.Commit(context.Background()), IsNil) 687 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, true) 688 689 // for add defCausumn 690 uFIDelateTest(&tests[4]) 691 addingDefCausName := "defCausA" 692 newDeferredCausetDef := &ast.DeferredCausetDef{ 693 Name: &ast.DeferredCausetName{Name: perceptron.NewCIStr(addingDefCausName)}, 694 Tp: &types.FieldType{Tp: allegrosql.TypeLonglong}, 695 Options: []*ast.DeferredCausetOption{}, 696 } 697 chs, defCausl := charset.GetDefaultCharsetAndDefCauslate() 698 defCaus, _, err := buildDeferredCausetAndConstraint(ctx, 2, newDeferredCausetDef, nil, chs, defCausl) 699 c.Assert(err, IsNil) 700 701 addDeferredCausetArgs := []interface{}{defCaus, &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionNone}, 0} 702 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCauset, addDeferredCausetArgs, &cancelState) 703 c.Check(errors.ErrorStack(checkErr), Equals, "") 704 s.checkAddDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{addingDefCausName}, false) 705 706 uFIDelateTest(&tests[5]) 707 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCauset, addDeferredCausetArgs, &cancelState) 708 c.Check(errors.ErrorStack(checkErr), Equals, "") 709 s.checkAddDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{addingDefCausName}, false) 710 711 uFIDelateTest(&tests[6]) 712 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCauset, addDeferredCausetArgs, &cancelState) 713 c.Check(errors.ErrorStack(checkErr), Equals, "") 714 s.checkAddDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{addingDefCausName}, false) 715 716 uFIDelateTest(&tests[7]) 717 testAddDeferredCauset(c, ctx, d, dbInfo, tblInfo, addDeferredCausetArgs) 718 c.Check(errors.ErrorStack(checkErr), Equals, "") 719 s.checkAddDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{addingDefCausName}, true) 720 721 // for create causet 722 tblInfo1 := testBlockInfo(c, d, "t1", 2) 723 uFIDelateTest(&tests[8]) 724 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo1.ID, perceptron.CausetActionCreateBlock, []interface{}{tblInfo1}, &cancelState) 725 c.Check(checkErr, IsNil) 726 testCheckBlockState(c, d, dbInfo, tblInfo1, perceptron.StateNone) 727 728 // for create database 729 dbInfo1 := testSchemaInfo(c, d, "test_cancel_job1") 730 uFIDelateTest(&tests[9]) 731 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo1.ID, 0, perceptron.CausetActionCreateSchema, []interface{}{dbInfo1}, &cancelState) 732 c.Check(checkErr, IsNil) 733 testCheckSchemaState(c, d, dbInfo1, perceptron.StateNone) 734 735 // for drop defCausumn. 736 uFIDelateTest(&tests[10]) 737 dropDefCausName := "c3" 738 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{dropDefCausName}, false) 739 testDropDeferredCauset(c, ctx, d, dbInfo, tblInfo, dropDefCausName, false) 740 c.Check(errors.ErrorStack(checkErr), Equals, "") 741 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{dropDefCausName}, true) 742 743 uFIDelateTest(&tests[11]) 744 dropDefCausName = "c4" 745 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{dropDefCausName}, false) 746 testDropDeferredCauset(c, ctx, d, dbInfo, tblInfo, dropDefCausName, false) 747 c.Check(errors.ErrorStack(checkErr), Equals, "") 748 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{dropDefCausName}, true) 749 750 uFIDelateTest(&tests[12]) 751 dropDefCausName = "c5" 752 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{dropDefCausName}, false) 753 testDropDeferredCauset(c, ctx, d, dbInfo, tblInfo, dropDefCausName, false) 754 c.Check(errors.ErrorStack(checkErr), Equals, "") 755 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, []string{dropDefCausName}, true) 756 757 // cancel rebase auto id 758 uFIDelateTest(&tests[13]) 759 rebaseIDArgs := []interface{}{int64(200)} 760 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionRebaseAutoID, rebaseIDArgs, &cancelState) 761 c.Check(errors.ErrorStack(checkErr), Equals, "") 762 changedBlock := testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 763 c.Assert(changedBlock.Meta().AutoIncID, Equals, blockAutoID) 764 765 // cancel shard bits 766 uFIDelateTest(&tests[14]) 767 shardRowIDArgs := []interface{}{uint64(7)} 768 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionShardRowID, shardRowIDArgs, &cancelState) 769 c.Check(checkErr, IsNil) 770 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 771 c.Assert(changedBlock.Meta().ShardRowIDBits, Equals, shardRowIDBits) 772 773 // modify none-state defCausumn 774 defCaus.DefaultValue = "1" 775 uFIDelateTest(&tests[15]) 776 modifyDeferredCausetArgs := []interface{}{defCaus, defCaus.Name, &ast.DeferredCausetPosition{}, byte(0)} 777 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, modifyDeferredCausetArgs, &test.cancelState) 778 c.Check(checkErr, IsNil) 779 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 780 changedDefCaus := perceptron.FindDeferredCausetInfo(changedBlock.Meta().DeferredCausets, defCaus.Name.L) 781 c.Assert(changedDefCaus.DefaultValue, IsNil) 782 783 // modify delete-only-state defCausumn, 784 defCaus.FieldType.Tp = allegrosql.TypeTiny 785 defCaus.FieldType.Flen = defCaus.FieldType.Flen - 1 786 uFIDelateTest(&tests[16]) 787 modifyDeferredCausetArgs = []interface{}{defCaus, defCaus.Name, &ast.DeferredCausetPosition{}, byte(0)} 788 doDBSJobSuccess(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, modifyDeferredCausetArgs) 789 c.Check(checkErr, IsNil) 790 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 791 changedDefCaus = perceptron.FindDeferredCausetInfo(changedBlock.Meta().DeferredCausets, defCaus.Name.L) 792 c.Assert(changedDefCaus.FieldType.Tp, Equals, allegrosql.TypeTiny) 793 c.Assert(changedDefCaus.FieldType.Flen, Equals, defCaus.FieldType.Flen) 794 defCaus.FieldType.Flen++ 795 796 // Test add foreign key failed cause by canceled. 797 uFIDelateTest(&tests[17]) 798 addForeignKeyArgs := []interface{}{perceptron.FKInfo{Name: perceptron.NewCIStr("fk1")}} 799 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, addForeignKeyArgs, &test.cancelState) 800 c.Check(checkErr, IsNil) 801 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 802 c.Assert(len(changedBlock.Meta().ForeignKeys), Equals, 0) 803 804 // Test add foreign key successful. 805 uFIDelateTest(&tests[18]) 806 doDBSJobSuccess(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, addForeignKeyArgs) 807 c.Check(checkErr, IsNil) 808 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 809 c.Assert(len(changedBlock.Meta().ForeignKeys), Equals, 1) 810 c.Assert(changedBlock.Meta().ForeignKeys[0].Name, Equals, addForeignKeyArgs[0].(perceptron.FKInfo).Name) 811 812 // Test drop foreign key failed cause by canceled. 813 uFIDelateTest(&tests[19]) 814 dropForeignKeyArgs := []interface{}{addForeignKeyArgs[0].(perceptron.FKInfo).Name} 815 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, dropForeignKeyArgs, &test.cancelState) 816 c.Check(checkErr, IsNil) 817 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 818 c.Assert(len(changedBlock.Meta().ForeignKeys), Equals, 1) 819 c.Assert(changedBlock.Meta().ForeignKeys[0].Name, Equals, dropForeignKeyArgs[0].(perceptron.CIStr)) 820 821 // Test drop foreign key successful. 822 uFIDelateTest(&tests[20]) 823 doDBSJobSuccess(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, dropForeignKeyArgs) 824 c.Check(checkErr, IsNil) 825 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 826 c.Assert(len(changedBlock.Meta().ForeignKeys), Equals, 0) 827 828 // test rename causet failed caused by canceled. 829 test = &tests[21] 830 renameBlockArgs := []interface{}{dbInfo.ID, perceptron.NewCIStr("t2")} 831 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, renameBlockArgs, &test.cancelState) 832 c.Check(checkErr, IsNil) 833 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 834 c.Assert(changedBlock.Meta().Name.L, Equals, "t") 835 836 // test rename causet successful. 837 test = &tests[22] 838 doDBSJobSuccess(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, renameBlockArgs) 839 c.Check(checkErr, IsNil) 840 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 841 c.Assert(changedBlock.Meta().Name.L, Equals, "t2") 842 843 // test modify causet charset failed caused by canceled. 844 test = &tests[23] 845 modifyBlockCharsetArgs := []interface{}{"utf8mb4", "utf8mb4_bin"} 846 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, modifyBlockCharsetArgs, &test.cancelState) 847 c.Check(checkErr, IsNil) 848 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 849 c.Assert(changedBlock.Meta().Charset, Equals, "utf8") 850 c.Assert(changedBlock.Meta().DefCauslate, Equals, "utf8_bin") 851 852 // test modify causet charset successfully. 853 test = &tests[24] 854 doDBSJobSuccess(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, modifyBlockCharsetArgs) 855 c.Check(checkErr, IsNil) 856 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 857 c.Assert(changedBlock.Meta().Charset, Equals, "utf8mb4") 858 c.Assert(changedBlock.Meta().DefCauslate, Equals, "utf8mb4_bin") 859 860 // test truncate causet partition failed caused by canceled. 861 test = &tests[25] 862 truncateTblPartitionArgs := []interface{}{[]int64{partitionTblInfo.Partition.Definitions[0].ID}} 863 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, partitionTblInfo.ID, test.act, truncateTblPartitionArgs, &test.cancelState) 864 c.Check(checkErr, IsNil) 865 changedBlock = testGetBlock(c, d, dbInfo.ID, partitionTblInfo.ID) 866 c.Assert(changedBlock.Meta().Partition.Definitions[0].ID == partitionTblInfo.Partition.Definitions[0].ID, IsTrue) 867 868 // test truncate causet partition charset successfully. 869 test = &tests[26] 870 doDBSJobSuccess(ctx, d, c, dbInfo.ID, partitionTblInfo.ID, test.act, truncateTblPartitionArgs) 871 c.Check(checkErr, IsNil) 872 changedBlock = testGetBlock(c, d, dbInfo.ID, partitionTblInfo.ID) 873 c.Assert(changedBlock.Meta().Partition.Definitions[0].ID == partitionTblInfo.Partition.Definitions[0].ID, IsFalse) 874 875 // test modify schemaReplicant charset failed caused by canceled. 876 test = &tests[27] 877 charsetAndDefCauslate := []interface{}{"utf8mb4", "utf8mb4_bin"} 878 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, charsetAndDefCauslate, &test.cancelState) 879 c.Check(checkErr, IsNil) 880 dbInfo, err = testGetSchemaInfoWithError(d, dbInfo.ID) 881 c.Assert(err, IsNil) 882 c.Assert(dbInfo.Charset, Equals, "") 883 c.Assert(dbInfo.DefCauslate, Equals, "") 884 885 // test modify causet charset successfully. 886 test = &tests[28] 887 doDBSJobSuccess(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, charsetAndDefCauslate) 888 c.Check(checkErr, IsNil) 889 dbInfo, err = testGetSchemaInfoWithError(d, dbInfo.ID) 890 c.Assert(err, IsNil) 891 c.Assert(dbInfo.Charset, Equals, "utf8mb4") 892 c.Assert(dbInfo.DefCauslate, Equals, "utf8mb4_bin") 893 894 // for adding primary key 895 tblInfo = changedBlock.Meta() 896 uFIDelateTest(&tests[29]) 897 idxOrigName = "primary" 898 validArgs = []interface{}{false, perceptron.NewCIStr(idxOrigName), 899 []*ast.IndexPartSpecification{{ 900 DeferredCauset: &ast.DeferredCausetName{Name: perceptron.NewCIStr("c1")}, 901 Length: -1, 902 }}, nil} 903 cancelState = perceptron.StateNone 904 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddPrimaryKey, validArgs, &cancelState) 905 c.Check(errors.ErrorStack(checkErr), Equals, "") 906 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, false) 907 uFIDelateTest(&tests[30]) 908 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddPrimaryKey, validArgs, &cancelState) 909 c.Check(errors.ErrorStack(checkErr), Equals, "") 910 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, false) 911 uFIDelateTest(&tests[31]) 912 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddPrimaryKey, validArgs, &cancelState) 913 c.Check(errors.ErrorStack(checkErr), Equals, "") 914 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, false) 915 uFIDelateTest(&tests[32]) 916 testCreatePrimaryKey(c, ctx, d, dbInfo, tblInfo, "c1") 917 c.Check(errors.ErrorStack(checkErr), Equals, "") 918 txn, err = ctx.Txn(true) 919 c.Assert(err, IsNil) 920 c.Assert(txn.Commit(context.Background()), IsNil) 921 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, true) 922 923 // for dropping primary key 924 uFIDelateTest(&tests[33]) 925 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionDropPrimaryKey, validArgs, &cancelState) 926 c.Check(errors.ErrorStack(checkErr), Equals, "") 927 s.checkDropIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, false) 928 uFIDelateTest(&tests[34]) 929 testDropIndex(c, ctx, d, dbInfo, tblInfo, idxOrigName) 930 c.Check(errors.ErrorStack(checkErr), Equals, "") 931 s.checkDropIdx(c, d, dbInfo.ID, tblInfo.ID, idxOrigName, true) 932 933 // for add defCausumns 934 uFIDelateTest(&tests[35]) 935 addingDefCausNames := []string{"defCausA", "defCausB", "defCausC", "defCausD", "defCausE", "defCausF"} 936 defcaus := make([]*causet.DeferredCauset, len(addingDefCausNames)) 937 for i, addingDefCausName := range addingDefCausNames { 938 newDeferredCausetDef := &ast.DeferredCausetDef{ 939 Name: &ast.DeferredCausetName{Name: perceptron.NewCIStr(addingDefCausName)}, 940 Tp: &types.FieldType{Tp: allegrosql.TypeLonglong}, 941 Options: []*ast.DeferredCausetOption{}, 942 } 943 defCaus, _, err := buildDeferredCausetAndConstraint(ctx, 0, newDeferredCausetDef, nil, allegrosql.DefaultCharset, "") 944 c.Assert(err, IsNil) 945 defcaus[i] = defCaus 946 } 947 offsets := make([]int, len(defcaus)) 948 positions := make([]*ast.DeferredCausetPosition, len(defcaus)) 949 for i := range positions { 950 positions[i] = &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionNone} 951 } 952 ifNotExists := make([]bool, len(defcaus)) 953 954 addDeferredCausetArgs = []interface{}{defcaus, positions, offsets, ifNotExists} 955 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCausets, addDeferredCausetArgs, &cancelState) 956 c.Check(errors.ErrorStack(checkErr), Equals, "") 957 s.checkAddDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, addingDefCausNames, false) 958 959 uFIDelateTest(&tests[36]) 960 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCausets, addDeferredCausetArgs, &cancelState) 961 c.Check(errors.ErrorStack(checkErr), Equals, "") 962 s.checkAddDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, addingDefCausNames, false) 963 964 uFIDelateTest(&tests[37]) 965 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, perceptron.CausetActionAddDeferredCausets, addDeferredCausetArgs, &cancelState) 966 c.Check(errors.ErrorStack(checkErr), Equals, "") 967 s.checkAddDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, addingDefCausNames, false) 968 969 uFIDelateTest(&tests[38]) 970 testAddDeferredCausets(c, ctx, d, dbInfo, tblInfo, addDeferredCausetArgs) 971 c.Check(errors.ErrorStack(checkErr), Equals, "") 972 s.checkAddDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, addingDefCausNames, true) 973 974 // for drop defCausumns 975 uFIDelateTest(&tests[39]) 976 dropDefCausNames := []string{"defCausA", "defCausB"} 977 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, dropDefCausNames, false) 978 testDropDeferredCausets(c, ctx, d, dbInfo, tblInfo, dropDefCausNames, false) 979 c.Check(errors.ErrorStack(checkErr), Equals, "") 980 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, dropDefCausNames, true) 981 982 uFIDelateTest(&tests[40]) 983 dropDefCausNames = []string{"defCausC", "defCausD"} 984 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, dropDefCausNames, false) 985 testDropDeferredCausets(c, ctx, d, dbInfo, tblInfo, dropDefCausNames, false) 986 c.Check(errors.ErrorStack(checkErr), Equals, "") 987 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, dropDefCausNames, true) 988 989 uFIDelateTest(&tests[41]) 990 dropDefCausNames = []string{"defCausE", "defCausF"} 991 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, dropDefCausNames, false) 992 testDropDeferredCausets(c, ctx, d, dbInfo, tblInfo, dropDefCausNames, false) 993 c.Check(errors.ErrorStack(checkErr), Equals, "") 994 s.checkCancelDropDeferredCausets(c, d, dbInfo.ID, tblInfo.ID, dropDefCausNames, true) 995 996 // test alter index visibility failed caused by canceled. 997 indexName := "idx_c3" 998 testCreateIndex(c, ctx, d, dbInfo, tblInfo, false, indexName, "c3") 999 c.Check(errors.ErrorStack(checkErr), Equals, "") 1000 txn, err = ctx.Txn(true) 1001 c.Assert(err, IsNil) 1002 c.Assert(txn.Commit(context.Background()), IsNil) 1003 s.checkAddIdx(c, d, dbInfo.ID, tblInfo.ID, indexName, true) 1004 1005 uFIDelateTest(&tests[42]) 1006 alterIndexVisibility := []interface{}{perceptron.NewCIStr(indexName), true} 1007 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, alterIndexVisibility, &test.cancelState) 1008 c.Check(checkErr, IsNil) 1009 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 1010 c.Assert(checkIdxVisibility(changedBlock, indexName, false), IsTrue) 1011 1012 // cancel alter index visibility successfully 1013 uFIDelateTest(&tests[43]) 1014 alterIndexVisibility = []interface{}{perceptron.NewCIStr(indexName), true} 1015 doDBSJobSuccess(ctx, d, c, dbInfo.ID, tblInfo.ID, test.act, alterIndexVisibility) 1016 c.Check(checkErr, IsNil) 1017 changedBlock = testGetBlock(c, d, dbInfo.ID, tblInfo.ID) 1018 c.Assert(checkIdxVisibility(changedBlock, indexName, true), IsTrue) 1019 1020 // test exchange partition failed caused by canceled 1021 pt := testBlockInfoWithPartition(c, d, "pt", 5) 1022 nt := testBlockInfo(c, d, "nt", 5) 1023 testCreateBlock(c, ctx, d, dbInfo, pt) 1024 testCreateBlock(c, ctx, d, dbInfo, nt) 1025 1026 uFIDelateTest(&tests[44]) 1027 defID := pt.Partition.Definitions[0].ID 1028 exchangeBlockPartition := []interface{}{defID, dbInfo.ID, pt.ID, "p0", true} 1029 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, nt.ID, test.act, exchangeBlockPartition, &test.cancelState) 1030 c.Check(checkErr, IsNil) 1031 changedNtBlock := testGetBlock(c, d, dbInfo.ID, nt.ID) 1032 changedPtBlock := testGetBlock(c, d, dbInfo.ID, pt.ID) 1033 c.Assert(changedNtBlock.Meta().ID == nt.ID, IsTrue) 1034 c.Assert(changedPtBlock.Meta().Partition.Definitions[0].ID == pt.Partition.Definitions[0].ID, IsTrue) 1035 1036 // cancel exchange partition successfully 1037 uFIDelateTest(&tests[45]) 1038 doDBSJobSuccess(ctx, d, c, dbInfo.ID, nt.ID, test.act, exchangeBlockPartition) 1039 c.Check(checkErr, IsNil) 1040 changedNtBlock = testGetBlock(c, d, dbInfo.ID, pt.Partition.Definitions[0].ID) 1041 changedPtBlock = testGetBlock(c, d, dbInfo.ID, pt.ID) 1042 c.Assert(changedNtBlock.Meta().ID == nt.ID, IsFalse) 1043 c.Assert(changedPtBlock.Meta().Partition.Definitions[0].ID == nt.ID, IsTrue) 1044 1045 // Cancel add causet partition. 1046 baseBlockInfo := testBlockInfoWithPartitionLessThan(c, d, "empty_block", 5, "1000") 1047 testCreateBlock(c, ctx, d, dbInfo, baseBlockInfo) 1048 1049 cancelState = perceptron.StateNone 1050 uFIDelateTest(&tests[46]) 1051 addedPartInfo := testAddedNewBlockPartitionInfo(c, d, baseBlockInfo, "p1", "maxvalue") 1052 addPartitionArgs := []interface{}{addedPartInfo} 1053 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, baseBlockInfo.ID, test.act, addPartitionArgs, &cancelState) 1054 c.Check(checkErr, IsNil) 1055 baseBlock := testGetBlock(c, d, dbInfo.ID, baseBlockInfo.ID) 1056 c.Assert(len(baseBlock.Meta().Partition.Definitions), Equals, 1) 1057 1058 uFIDelateTest(&tests[47]) 1059 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, baseBlockInfo.ID, test.act, addPartitionArgs, &cancelState) 1060 c.Check(checkErr, IsNil) 1061 baseBlock = testGetBlock(c, d, dbInfo.ID, baseBlockInfo.ID) 1062 c.Assert(len(baseBlock.Meta().Partition.Definitions), Equals, 1) 1063 1064 uFIDelateTest(&tests[48]) 1065 doDBSJobSuccess(ctx, d, c, dbInfo.ID, baseBlockInfo.ID, test.act, addPartitionArgs) 1066 c.Check(checkErr, IsNil) 1067 baseBlock = testGetBlock(c, d, dbInfo.ID, baseBlockInfo.ID) 1068 c.Assert(len(baseBlock.Meta().Partition.Definitions), Equals, 2) 1069 c.Assert(baseBlock.Meta().Partition.Definitions[1].ID, Equals, addedPartInfo.Definitions[0].ID) 1070 c.Assert(baseBlock.Meta().Partition.Definitions[1].LessThan[0], Equals, addedPartInfo.Definitions[0].LessThan[0]) 1071 1072 // Cancel modify defCausumn which should reorg the data. 1073 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/dbs/skipMockContextDoInterDirc", `return(true)`), IsNil) 1074 baseBlockInfo = testBlockInfoWith2IndexOnFirstDeferredCauset(c, d, "modify-causet", 2) 1075 // This will cost 2 global id, one for causet id, the other for the job id. 1076 testCreateBlock(c, ctx, d, dbInfo, baseBlockInfo) 1077 1078 cancelState = perceptron.StateNone 1079 newDefCaus := baseBlockInfo.DeferredCausets[0].Clone() 1080 // change type from long to tinyint. 1081 newDefCaus.FieldType = *types.NewFieldType(allegrosql.TypeTiny) 1082 // change from null to not null 1083 newDefCaus.FieldType.Flag |= allegrosql.NotNullFlag 1084 newDefCaus.FieldType.Flen = 2 1085 1086 originDefCausName := baseBlockInfo.DeferredCausets[0].Name 1087 pos := &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionNone} 1088 1089 uFIDelateTest(&tests[49]) 1090 modifyDeferredCausetArgs = []interface{}{&newDefCaus, originDefCausName, pos, allegrosql.TypeNull, 0} 1091 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, baseBlockInfo.ID, test.act, modifyDeferredCausetArgs, &cancelState) 1092 c.Check(checkErr, IsNil) 1093 baseBlock = testGetBlock(c, d, dbInfo.ID, baseBlockInfo.ID) 1094 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Tp, Equals, allegrosql.TypeLong) 1095 c.Assert(allegrosql.HasNotNullFlag(baseBlock.Meta().DeferredCausets[0].FieldType.Flag), Equals, false) 1096 1097 uFIDelateTest(&tests[50]) 1098 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, baseBlockInfo.ID, test.act, modifyDeferredCausetArgs, &cancelState) 1099 c.Check(checkErr, IsNil) 1100 baseBlock = testGetBlock(c, d, dbInfo.ID, baseBlockInfo.ID) 1101 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Tp, Equals, allegrosql.TypeLong) 1102 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Flag&allegrosql.NotNullFlag, Equals, uint(0)) 1103 1104 uFIDelateTest(&tests[51]) 1105 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, baseBlockInfo.ID, test.act, modifyDeferredCausetArgs, &cancelState) 1106 c.Check(checkErr, IsNil) 1107 baseBlock = testGetBlock(c, d, dbInfo.ID, baseBlockInfo.ID) 1108 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Tp, Equals, allegrosql.TypeLong) 1109 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Flag&allegrosql.NotNullFlag, Equals, uint(0)) 1110 1111 uFIDelateTest(&tests[52]) 1112 doDBSJobErrWithSchemaState(ctx, d, c, dbInfo.ID, baseBlockInfo.ID, test.act, modifyDeferredCausetArgs, &cancelState) 1113 c.Check(checkErr, IsNil) 1114 baseBlock = testGetBlock(c, d, dbInfo.ID, baseBlockInfo.ID) 1115 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Tp, Equals, allegrosql.TypeLong) 1116 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Flag&allegrosql.NotNullFlag, Equals, uint(0)) 1117 1118 uFIDelateTest(&tests[53]) 1119 doDBSJobSuccess(ctx, d, c, dbInfo.ID, baseBlockInfo.ID, test.act, modifyDeferredCausetArgs) 1120 c.Check(checkErr, IsNil) 1121 baseBlock = testGetBlock(c, d, dbInfo.ID, baseBlockInfo.ID) 1122 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Tp, Equals, allegrosql.TypeTiny) 1123 c.Assert(baseBlock.Meta().DeferredCausets[0].FieldType.Flag&allegrosql.NotNullFlag, Equals, uint(1)) 1124 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/dbs/skipMockContextDoInterDirc"), IsNil) 1125 } 1126 1127 func (s *testDBSSuite) TestIgnorableSpec(c *C) { 1128 specs := []ast.AlterBlockType{ 1129 ast.AlterBlockOption, 1130 ast.AlterBlockAddDeferredCausets, 1131 ast.AlterBlockAddConstraint, 1132 ast.AlterBlockDropDeferredCauset, 1133 ast.AlterBlockDropPrimaryKey, 1134 ast.AlterBlockDropIndex, 1135 ast.AlterBlockDropForeignKey, 1136 ast.AlterBlockModifyDeferredCauset, 1137 ast.AlterBlockChangeDeferredCauset, 1138 ast.AlterBlockRenameBlock, 1139 ast.AlterBlockAlterDeferredCauset, 1140 } 1141 for _, spec := range specs { 1142 c.Assert(isIgnorableSpec(spec), IsFalse) 1143 } 1144 1145 ignorableSpecs := []ast.AlterBlockType{ 1146 ast.AlterBlockLock, 1147 ast.AlterBlockAlgorithm, 1148 } 1149 for _, spec := range ignorableSpecs { 1150 c.Assert(isIgnorableSpec(spec), IsTrue) 1151 } 1152 } 1153 1154 func (s *testDBSSuite) TestBuildJobDependence(c *C) { 1155 causetstore := testCreateStore(c, "test_set_job_relation") 1156 defer causetstore.Close() 1157 1158 // Add some non-add-index jobs. 1159 job1 := &perceptron.Job{ID: 1, BlockID: 1, Type: perceptron.CausetActionAddDeferredCauset} 1160 job2 := &perceptron.Job{ID: 2, BlockID: 1, Type: perceptron.CausetActionCreateBlock} 1161 job3 := &perceptron.Job{ID: 3, BlockID: 2, Type: perceptron.CausetActionDropDeferredCauset} 1162 job6 := &perceptron.Job{ID: 6, BlockID: 1, Type: perceptron.CausetActionDropBlock} 1163 job7 := &perceptron.Job{ID: 7, BlockID: 2, Type: perceptron.CausetActionModifyDeferredCauset} 1164 job9 := &perceptron.Job{ID: 9, SchemaID: 111, Type: perceptron.CausetActionDropSchema} 1165 job11 := &perceptron.Job{ID: 11, BlockID: 2, Type: perceptron.CausetActionRenameBlock, Args: []interface{}{int64(111), "old EDB name"}} 1166 ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 1167 t := spacetime.NewMeta(txn) 1168 err := t.EnQueueDBSJob(job1) 1169 c.Assert(err, IsNil) 1170 err = t.EnQueueDBSJob(job2) 1171 c.Assert(err, IsNil) 1172 err = t.EnQueueDBSJob(job3) 1173 c.Assert(err, IsNil) 1174 err = t.EnQueueDBSJob(job6) 1175 c.Assert(err, IsNil) 1176 err = t.EnQueueDBSJob(job7) 1177 c.Assert(err, IsNil) 1178 err = t.EnQueueDBSJob(job9) 1179 c.Assert(err, IsNil) 1180 err = t.EnQueueDBSJob(job11) 1181 c.Assert(err, IsNil) 1182 return nil 1183 }) 1184 job4 := &perceptron.Job{ID: 4, BlockID: 1, Type: perceptron.CausetActionAddIndex} 1185 ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 1186 t := spacetime.NewMeta(txn) 1187 err := buildJobDependence(t, job4) 1188 c.Assert(err, IsNil) 1189 c.Assert(job4.DependencyID, Equals, int64(2)) 1190 return nil 1191 }) 1192 job5 := &perceptron.Job{ID: 5, BlockID: 2, Type: perceptron.CausetActionAddIndex} 1193 ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 1194 t := spacetime.NewMeta(txn) 1195 err := buildJobDependence(t, job5) 1196 c.Assert(err, IsNil) 1197 c.Assert(job5.DependencyID, Equals, int64(3)) 1198 return nil 1199 }) 1200 job8 := &perceptron.Job{ID: 8, BlockID: 3, Type: perceptron.CausetActionAddIndex} 1201 ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 1202 t := spacetime.NewMeta(txn) 1203 err := buildJobDependence(t, job8) 1204 c.Assert(err, IsNil) 1205 c.Assert(job8.DependencyID, Equals, int64(0)) 1206 return nil 1207 }) 1208 job10 := &perceptron.Job{ID: 10, SchemaID: 111, BlockID: 3, Type: perceptron.CausetActionAddIndex} 1209 ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 1210 t := spacetime.NewMeta(txn) 1211 err := buildJobDependence(t, job10) 1212 c.Assert(err, IsNil) 1213 c.Assert(job10.DependencyID, Equals, int64(9)) 1214 return nil 1215 }) 1216 job12 := &perceptron.Job{ID: 12, SchemaID: 112, BlockID: 2, Type: perceptron.CausetActionAddIndex} 1217 ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 1218 t := spacetime.NewMeta(txn) 1219 err := buildJobDependence(t, job12) 1220 c.Assert(err, IsNil) 1221 c.Assert(job12.DependencyID, Equals, int64(11)) 1222 return nil 1223 }) 1224 } 1225 1226 func addDBSJob(c *C, d *dbs, job *perceptron.Job) { 1227 task := &limitJobTask{job, make(chan error)} 1228 d.limitJobCh <- task 1229 err := <-task.err 1230 c.Assert(err, IsNil) 1231 } 1232 1233 func (s *testDBSSuite) TestParallelDBS(c *C) { 1234 causetstore := testCreateStore(c, "test_parallel_dbs") 1235 defer causetstore.Close() 1236 d := testNewDBSAndStart( 1237 context.Background(), 1238 c, 1239 WithStore(causetstore), 1240 WithLease(testLease), 1241 ) 1242 defer d.Stop() 1243 ctx := testNewContext(d) 1244 err := ctx.NewTxn(context.Background()) 1245 c.Assert(err, IsNil) 1246 /* 1247 build structure: 1248 DBs -> { 1249 db1: test_parallel_dbs_1 1250 db2: test_parallel_dbs_2 1251 } 1252 Blocks -> { 1253 db1.t1 (c1 int, c2 int) 1254 db1.t2 (c1 int primary key, c2 int, c3 int) 1255 db2.t3 (c1 int, c2 int, c3 int, c4 int) 1256 } 1257 Data -> { 1258 t1: (10, 10), (20, 20) 1259 t2: (1, 1, 1), (2, 2, 2), (3, 3, 3) 1260 t3: (11, 22, 33, 44) 1261 } 1262 */ 1263 // create database test_parallel_dbs_1; 1264 dbInfo1 := testSchemaInfo(c, d, "test_parallel_dbs_1") 1265 testCreateSchema(c, ctx, d, dbInfo1) 1266 // create causet t1 (c1 int, c2 int); 1267 tblInfo1 := testBlockInfo(c, d, "t1", 2) 1268 testCreateBlock(c, ctx, d, dbInfo1, tblInfo1) 1269 // insert t1 values (10, 10), (20, 20) 1270 tbl1 := testGetBlock(c, d, dbInfo1.ID, tblInfo1.ID) 1271 _, err = tbl1.AddRecord(ctx, types.MakeCausets(1, 1)) 1272 c.Assert(err, IsNil) 1273 _, err = tbl1.AddRecord(ctx, types.MakeCausets(2, 2)) 1274 c.Assert(err, IsNil) 1275 // create causet t2 (c1 int primary key, c2 int, c3 int); 1276 tblInfo2 := testBlockInfo(c, d, "t2", 3) 1277 tblInfo2.DeferredCausets[0].Flag = allegrosql.PriKeyFlag | allegrosql.NotNullFlag 1278 tblInfo2.PKIsHandle = true 1279 testCreateBlock(c, ctx, d, dbInfo1, tblInfo2) 1280 // insert t2 values (1, 1), (2, 2), (3, 3) 1281 tbl2 := testGetBlock(c, d, dbInfo1.ID, tblInfo2.ID) 1282 _, err = tbl2.AddRecord(ctx, types.MakeCausets(1, 1, 1)) 1283 c.Assert(err, IsNil) 1284 _, err = tbl2.AddRecord(ctx, types.MakeCausets(2, 2, 2)) 1285 c.Assert(err, IsNil) 1286 _, err = tbl2.AddRecord(ctx, types.MakeCausets(3, 3, 3)) 1287 c.Assert(err, IsNil) 1288 // create database test_parallel_dbs_2; 1289 dbInfo2 := testSchemaInfo(c, d, "test_parallel_dbs_2") 1290 testCreateSchema(c, ctx, d, dbInfo2) 1291 // create causet t3 (c1 int, c2 int, c3 int, c4 int); 1292 tblInfo3 := testBlockInfo(c, d, "t3", 4) 1293 testCreateBlock(c, ctx, d, dbInfo2, tblInfo3) 1294 // insert t3 values (11, 22, 33, 44) 1295 tbl3 := testGetBlock(c, d, dbInfo2.ID, tblInfo3.ID) 1296 _, err = tbl3.AddRecord(ctx, types.MakeCausets(11, 22, 33, 44)) 1297 c.Assert(err, IsNil) 1298 1299 // set hook to execute jobs after all jobs are in queue. 1300 jobCnt := int64(11) 1301 tc := &TestDBSCallback{} 1302 once := sync.Once{} 1303 var checkErr error 1304 tc.onJobRunBefore = func(job *perceptron.Job) { 1305 // TODO: extract a unified function for other tests. 1306 once.Do(func() { 1307 qLen1 := int64(0) 1308 qLen2 := int64(0) 1309 for { 1310 checkErr = ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 1311 m := spacetime.NewMeta(txn) 1312 qLen1, err = m.DBSJobQueueLen() 1313 if err != nil { 1314 return err 1315 } 1316 qLen2, err = m.DBSJobQueueLen(spacetime.AddIndexJobListKey) 1317 if err != nil { 1318 return err 1319 } 1320 return nil 1321 }) 1322 if checkErr != nil { 1323 break 1324 } 1325 if qLen1+qLen2 == jobCnt { 1326 if qLen2 != 5 { 1327 checkErr = errors.Errorf("add index jobs cnt %v != 5", qLen2) 1328 } 1329 break 1330 } 1331 time.Sleep(5 * time.Millisecond) 1332 } 1333 }) 1334 } 1335 d.SetHook(tc) 1336 c.Assert(checkErr, IsNil) 1337 1338 /* 1339 prepare jobs: 1340 / job no. / database no. / causet no. / action type / 1341 / 1 / 1 / 1 / add index / 1342 / 2 / 1 / 1 / add defCausumn / 1343 / 3 / 1 / 1 / add index / 1344 / 4 / 1 / 2 / drop defCausumn / 1345 / 5 / 1 / 1 / drop index / 1346 / 6 / 1 / 2 / add index / 1347 / 7 / 2 / 3 / drop defCausumn / 1348 / 8 / 2 / 3 / rebase autoID/ 1349 / 9 / 1 / 1 / add index / 1350 / 10 / 2 / null / drop schemaReplicant / 1351 / 11 / 2 / 2 / add index / 1352 */ 1353 job1 := buildCreateIdxJob(dbInfo1, tblInfo1, false, "db1_idx1", "c1") 1354 addDBSJob(c, d, job1) 1355 job2 := buildCreateDeferredCausetJob(dbInfo1, tblInfo1, "c3", &ast.DeferredCausetPosition{Tp: ast.DeferredCausetPositionNone}, nil) 1356 addDBSJob(c, d, job2) 1357 job3 := buildCreateIdxJob(dbInfo1, tblInfo1, false, "db1_idx2", "c3") 1358 addDBSJob(c, d, job3) 1359 job4 := buildDropDeferredCausetJob(dbInfo1, tblInfo2, "c3") 1360 addDBSJob(c, d, job4) 1361 job5 := buildDropIdxJob(dbInfo1, tblInfo1, "db1_idx1") 1362 addDBSJob(c, d, job5) 1363 job6 := buildCreateIdxJob(dbInfo1, tblInfo2, false, "db2_idx1", "c2") 1364 addDBSJob(c, d, job6) 1365 job7 := buildDropDeferredCausetJob(dbInfo2, tblInfo3, "c4") 1366 addDBSJob(c, d, job7) 1367 job8 := buildRebaseAutoIDJobJob(dbInfo2, tblInfo3, 1024) 1368 addDBSJob(c, d, job8) 1369 job9 := buildCreateIdxJob(dbInfo1, tblInfo1, false, "db1_idx3", "c2") 1370 addDBSJob(c, d, job9) 1371 job10 := buildDropSchemaJob(dbInfo2) 1372 addDBSJob(c, d, job10) 1373 job11 := buildCreateIdxJob(dbInfo2, tblInfo3, false, "db3_idx1", "c2") 1374 addDBSJob(c, d, job11) 1375 // TODO: add rename causet job 1376 1377 // check results. 1378 isChecked := false 1379 for !isChecked { 1380 ekv.RunInNewTxn(causetstore, false, func(txn ekv.Transaction) error { 1381 m := spacetime.NewMeta(txn) 1382 lastJob, err := m.GetHistoryDBSJob(job11.ID) 1383 c.Assert(err, IsNil) 1384 // all jobs are finished. 1385 if lastJob != nil { 1386 finishedJobs, err := m.GetAllHistoryDBSJobs() 1387 c.Assert(err, IsNil) 1388 // get the last 11 jobs completed. 1389 finishedJobs = finishedJobs[len(finishedJobs)-11:] 1390 // check some jobs are ordered because of the dependence. 1391 c.Assert(finishedJobs[0].ID, Equals, job1.ID) 1392 c.Assert(finishedJobs[1].ID, Equals, job2.ID) 1393 c.Assert(finishedJobs[2].ID, Equals, job3.ID) 1394 c.Assert(finishedJobs[4].ID, Equals, job5.ID) 1395 c.Assert(finishedJobs[10].ID, Equals, job11.ID) 1396 // check the jobs are ordered in the adding-index-job queue or general-job queue. 1397 addIdxJobID := int64(0) 1398 generalJobID := int64(0) 1399 for _, job := range finishedJobs { 1400 // check jobs' order. 1401 if job.Type == perceptron.CausetActionAddIndex { 1402 c.Assert(job.ID, Greater, addIdxJobID) 1403 addIdxJobID = job.ID 1404 } else { 1405 c.Assert(job.ID, Greater, generalJobID) 1406 generalJobID = job.ID 1407 } 1408 // check jobs' state. 1409 if job.ID == lastJob.ID { 1410 c.Assert(job.State, Equals, perceptron.JobStateCancelled, Commentf("job: %v", job)) 1411 } else { 1412 c.Assert(job.State, Equals, perceptron.JobStateSynced, Commentf("job: %v", job)) 1413 } 1414 } 1415 1416 isChecked = true 1417 } 1418 return nil 1419 }) 1420 time.Sleep(10 * time.Millisecond) 1421 } 1422 1423 tc = &TestDBSCallback{} 1424 d.SetHook(tc) 1425 } 1426 1427 func (s *testDBSSuite) TestDBSPackageInterDircuteALLEGROSQL(c *C) { 1428 causetstore := testCreateStore(c, "test_run_sql") 1429 defer causetstore.Close() 1430 1431 d := testNewDBSAndStart( 1432 context.Background(), 1433 c, 1434 WithStore(causetstore), 1435 WithLease(testLease), 1436 ) 1437 testCheckTenant(c, d, true) 1438 defer d.Stop() 1439 worker := d.generalWorker() 1440 c.Assert(worker, NotNil) 1441 1442 // In test environment, worker.ctxPool will be nil, and get will return mock.Context. 1443 // We just test that can use it to call sqlexec.ALLEGROSQLInterlockingDirectorate.InterDircute. 1444 sess, err := worker.sessPool.get() 1445 c.Assert(err, IsNil) 1446 defer worker.sessPool.put(sess) 1447 se := sess.(sqlexec.ALLEGROSQLInterlockingDirectorate) 1448 _, _ = se.InterDircute(context.Background(), "create causet t(a int);") 1449 }