From e811eb7d226680e278a8484e4573bef382bb02b1 Mon Sep 17 00:00:00 2001 From: winkyao Date: Fri, 1 Mar 2019 17:49:49 +0800 Subject: [PATCH] ddl: fix canceling model.ActionRebaseAutoID and model.ActionShardRowID ddl jobs (#9226) (#9506) --- ddl/ddl_worker_test.go | 32 +++++++++++++++++++++++++++++--- ddl/rollingback.go | 12 ++++++++++++ util/admin/admin.go | 4 ++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/ddl/ddl_worker_test.go b/ddl/ddl_worker_test.go index b60b7ab23fa3e..ddfa6574f576f 100644 --- a/ddl/ddl_worker_test.go +++ b/ddl/ddl_worker_test.go @@ -303,8 +303,9 @@ func checkCancelState(txn kv.Transaction, job *model.Job, test *testCancelJob) e // 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. // When the job satisfies this case of addIndexFirstReorg, the worker hasn't started to backfill indexes. if test.cancelState == job.SchemaState && !addIndexFirstReorg { - if job.SchemaState == model.StateNone && job.State != model.JobStateDone && job.Type != model.ActionCreateTable && job.Type != model.ActionCreateSchema { - // If the schema state is none, we only test the job is finished. + if job.SchemaState == model.StateNone && job.State != model.JobStateDone && job.Type != model.ActionCreateTable && job.Type != model.ActionCreateSchema && job.Type != model.ActionRebaseAutoID { + // If the schema state is none and is not equal to model.JobStateDone, we only test the job is finished. + // Unless the job is model.ActionCreateTable, model.ActionCreateSchema, model.ActionRebaseAutoID, we do the cancel anyway. } else { errs, err := admin.CancelJobs(txn, test.jobIDs) if err != nil { @@ -353,6 +354,8 @@ func buildCancelJobTests(firstID int64) []testCancelJob { {act: model.ActionDropColumn, jobIDs: []int64{firstID + 13}, cancelRetErrs: []error{admin.ErrCannotCancelDDLJob.GenWithStackByArgs(firstID + 13)}, cancelState: model.StateDeleteOnly, ddlRetErr: err}, {act: model.ActionDropColumn, jobIDs: []int64{firstID + 14}, cancelRetErrs: []error{admin.ErrCannotCancelDDLJob.GenWithStackByArgs(firstID + 14)}, cancelState: model.StateWriteOnly, ddlRetErr: err}, {act: model.ActionDropColumn, jobIDs: []int64{firstID + 15}, cancelRetErrs: []error{admin.ErrCannotCancelDDLJob.GenWithStackByArgs(firstID + 15)}, cancelState: model.StateWriteReorganization, ddlRetErr: err}, + {act: model.ActionRebaseAutoID, jobIDs: []int64{firstID + 16}, cancelRetErrs: noErrs, cancelState: model.StateNone, ddlRetErr: err}, + {act: model.ActionShardRowID, jobIDs: []int64{firstID + 17}, cancelRetErrs: noErrs, cancelState: model.StateNone, ddlRetErr: err}, } return tests @@ -407,6 +410,11 @@ func (s *testDDLSuite) TestCancelJob(c *C) { ctx := testNewContext(d) err := ctx.NewTxn() c.Assert(err, IsNil) + tableAutoID := int64(100) + shardRowIDBits := uint64(5) + tblInfo.AutoIncID = tableAutoID + tblInfo.ShardRowIDBits = shardRowIDBits + job := testCreateTable(c, ctx, d, dbInfo, tblInfo) // insert t values (1, 2, 3, 4, 5); originTable := testGetTable(c, d, dbInfo.ID, tblInfo.ID) @@ -424,7 +432,7 @@ func (s *testDDLSuite) TestCancelJob(c *C) { tests := buildCancelJobTests(firstJobID) var checkErr error var test *testCancelJob - tc.onJobUpdated = func(job *model.Job) { + hookCancelFunc := func(job *model.Job) { if job.State == model.JobStateSynced || job.State == model.JobStateCancelled || job.State == model.JobStateCancelling { return } @@ -455,6 +463,8 @@ func (s *testDDLSuite) TestCancelJob(c *C) { return } } + tc.onJobUpdated = hookCancelFunc + tc.onJobRunBefore = hookCancelFunc d.SetHook(tc) // for adding index @@ -553,6 +563,22 @@ func (s *testDDLSuite) TestCancelJob(c *C) { testDropColumn(c, ctx, d, dbInfo, tblInfo, dropColName, false) c.Check(errors.ErrorStack(checkErr), Equals, "") s.checkCancelDropColumn(c, d, dbInfo.ID, tblInfo.ID, dropColName, true) + + // cancel rebase auto id + test = &tests[13] + rebaseIDArgs := []interface{}{int64(200)} + doDDLJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, model.ActionRebaseAutoID, rebaseIDArgs, &cancelState) + c.Check(errors.ErrorStack(checkErr), Equals, "") + changedTable := testGetTable(c, d, dbInfo.ID, tblInfo.ID) + c.Assert(changedTable.Meta().AutoIncID, Equals, tableAutoID) + + // cancel shard bits + test = &tests[14] + shardRowIDArgs := []interface{}{uint64(7)} + doDDLJobErrWithSchemaState(ctx, d, c, dbInfo.ID, tblInfo.ID, model.ActionRebaseAutoID, shardRowIDArgs, &cancelState) + c.Check(errors.ErrorStack(checkErr), Equals, "") + changedTable = testGetTable(c, d, dbInfo.ID, tblInfo.ID) + c.Assert(changedTable.Meta().ShardRowIDBits, Equals, shardRowIDBits) } func (s *testDDLSuite) TestIgnorableSpec(c *C) { diff --git a/ddl/rollingback.go b/ddl/rollingback.go index 02592d396e685..e283e4d6883cf 100644 --- a/ddl/rollingback.go +++ b/ddl/rollingback.go @@ -88,6 +88,14 @@ func cancelOnlyNotHandledJob(job *model.Job) (ver int64, err error) { return ver, nil } +func rollingbackRebaseAutoID(t *meta.Meta, job *model.Job) (ver int64, err error) { + return cancelOnlyNotHandledJob(job) +} + +func rollingbackShardRowID(t *meta.Meta, job *model.Job) (ver int64, err error) { + return cancelOnlyNotHandledJob(job) +} + func rollingbackAddColumn(t *meta.Meta, job *model.Job) (ver int64, err error) { job.State = model.JobStateRollingback col := &model.ColumnInfo{} @@ -266,6 +274,10 @@ func convertJob2RollbackJob(w *worker, d *ddlCtx, t *meta.Meta, job *model.Job) ver, err = rollingbackTruncateTable(t, job) case model.ActionDropIndex: ver, err = rollingbackDropIndex(t, job) + case model.ActionRebaseAutoID: + ver, err = rollingbackRebaseAutoID(t, job) + case model.ActionShardRowID: + ver, err = rollingbackShardRowID(t, job) case model.ActionDropTable, model.ActionDropSchema: job.State = model.JobStateRollingback default: diff --git a/util/admin/admin.go b/util/admin/admin.go index db07478d8921d..2ee4207898ed6 100644 --- a/util/admin/admin.go +++ b/util/admin/admin.go @@ -107,6 +107,10 @@ func isJobRollbackable(job *model.Job, id int64) error { job.SchemaState == model.StateDeleteReorganization { return ErrCannotCancelDDLJob.GenWithStackByArgs(id) } + case model.ActionRebaseAutoID, model.ActionShardRowID: + if job.SchemaState != model.StateNone { + return ErrCannotCancelDDLJob.GenWithStackByArgs(id) + } case model.ActionDropSchema, model.ActionDropTable: // To simplify the rollback logic, cannot be canceled in the following states. if job.SchemaState == model.StateWriteOnly ||