diff --git a/ddl/cancel_test.go b/ddl/cancel_test.go index 3f02029ffced7..558e8b06823a2 100644 --- a/ddl/cancel_test.go +++ b/ddl/cancel_test.go @@ -26,6 +26,7 @@ import ( "github.com/pingcap/tidb/errno" "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/testkit" + "github.com/pingcap/tidb/testkit/external" "github.com/stretchr/testify/require" atomicutil "go.uber.org/atomic" ) @@ -336,3 +337,40 @@ func TestCancel(t *testing.T) { } } } + +func TestCancelForAddUniqueIndex(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tkCancel := testkit.NewTestKit(t, store) + + // Prepare schema. + tk.MustExec("use test") + tk.MustExec(`create table t (c1 int, c2 int, c3 int)`) + tk.MustExec("insert into t values(1, 1, 1)") + tk.MustExec("insert into t values(2, 2, 2)") + tk.MustExec("insert into t values(1, 1, 1)") + + hook := &callback.TestDDLCallback{Do: dom} + var testCancelState model.SchemaState + hook.OnJobRunBeforeExported = func(job *model.Job) { + if job.SchemaState == testCancelState && job.State == model.JobStateRollingback { + tkCancel.MustExec(fmt.Sprintf("admin cancel ddl jobs %d", job.ID)) + } + } + dom.DDL().SetHook(hook.Clone()) + + testCancelState = model.StateWriteOnly + tk.MustGetErrCode("alter table t add unique index idx1(c1)", errno.ErrDupEntry) + tbl := external.GetTableByName(t, tk, "test", "t") + require.Equal(t, 0, len(tbl.Meta().Indices)) + + testCancelState = model.StateDeleteOnly + tk.MustGetErrCode("alter table t add unique index idx1(c1)", errno.ErrDupEntry) + tbl = external.GetTableByName(t, tk, "test", "t") + require.Equal(t, 0, len(tbl.Meta().Indices)) + + testCancelState = model.StateDeleteReorganization + tk.MustGetErrCode("alter table t add unique index idx1(c1)", errno.ErrDupEntry) + tbl = external.GetTableByName(t, tk, "test", "t") + require.Equal(t, 0, len(tbl.Meta().Indices)) +} diff --git a/ddl/ddl.go b/ddl/ddl.go index 5cb4c0d5dfe1c..5d765c990aa70 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -20,7 +20,6 @@ package ddl import ( "context" - "encoding/json" "fmt" "runtime" "strconv" @@ -1454,9 +1453,7 @@ func cancelRunningJob(sess *sess.Session, job *model.Job, } job.State = model.JobStateCancelling job.AdminOperator = byWho - - // Make sure RawArgs isn't overwritten. - return json.Unmarshal(job.RawArgs, &job.Args) + return nil } // pauseRunningJob check and pause the running Job @@ -1475,12 +1472,7 @@ func pauseRunningJob(sess *sess.Session, job *model.Job, job.State = model.JobStatePausing job.AdminOperator = byWho - - if job.RawArgs == nil { - return nil - } - - return json.Unmarshal(job.RawArgs, &job.Args) + return nil } // resumePausedJob check and resume the Paused Job @@ -1500,7 +1492,7 @@ func resumePausedJob(se *sess.Session, job *model.Job, job.State = model.JobStateQueueing - return json.Unmarshal(job.RawArgs, &job.Args) + return nil } // processJobs command on the Job according to the process @@ -1558,7 +1550,7 @@ func processJobs(process func(*sess.Session, *model.Job, model.AdminCommandOpera continue } - err = updateDDLJob2Table(ns, job, true) + err = updateDDLJob2Table(ns, job, false) if err != nil { errs[i] = err continue @@ -1642,7 +1634,7 @@ func processAllJobs(process func(*sess.Session, *model.Job, model.AdminCommandOp continue } - err = updateDDLJob2Table(ns, job, true) + err = updateDDLJob2Table(ns, job, false) if err != nil { jobErrs[job.ID] = err continue