Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ddl: fix bug of run ddl job error but actually take effect (#17341) #17608

Merged
merged 8 commits into from
Jun 5, 2020
9 changes: 9 additions & 0 deletions ddl/ddl_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,15 @@ func (w *worker) handleDDLJobQueue(d *ddlCtx) error {
err = w.finishDDLJob(t, job)
return errors.Trace(err)
}
if runJobErr != nil && !job.IsRollingback() && !job.IsRollbackDone() {
// If the running job meets an error
// and the job state is rolling back, it means that we have already handled this error.
// Some DDL jobs (such as adding indexes) may need to update the table info and the schema version,
// then shouldn't discard the KV modification.
// And the job state is rollback done, it means the job was already finished, also shouldn't discard too.
// Otherwise, we should discard the KV modification when running job.
txn.Discard()
}
err = w.updateDDLJob(t, job, runJobErr != nil)
if err = w.handleUpdateJobError(t, job, err); err != nil {
return errors.Trace(err)
Expand Down
21 changes: 21 additions & 0 deletions ddl/serial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,27 @@ func (s *testSerialSuite) TestCancelJobByErrorCountLimit(c *C) {
c.Assert(err.Error(), Equals, "[ddl:8214]Cancelled DDL job")
}

func (s *testSerialSuite) TestTruncateTableUpdateSchemaVersionErr(c *C) {
tk := testkit.NewTestKit(c, s.store)
c.Assert(failpoint.Enable("github.com/pingcap/tidb/ddl/mockTruncateTableUpdateVersionError", `return(true)`), IsNil)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")

limit := variable.GetDDLErrorCountLimit()
tk.MustExec("set @@global.tidb_ddl_error_count_limit = 5")
err := ddlutil.LoadDDLVars(tk.Se)
c.Assert(err, IsNil)
defer tk.MustExec(fmt.Sprintf("set @@global.tidb_ddl_error_count_limit = %d", limit))

tk.MustExec("create table t (a int)")
_, err = tk.Exec("truncate table t")
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "[ddl:8214]Cancelled DDL job")
// Disable fail point.
c.Assert(failpoint.Disable("github.com/pingcap/tidb/ddl/mockTruncateTableUpdateVersionError"), IsNil)
tk.MustExec("truncate table t")
}

func (s *testSerialSuite) TestCanceledJobTakeTime(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
Expand Down
6 changes: 6 additions & 0 deletions ddl/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,12 @@ func onTruncateTable(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ erro
return ver, errors.Trace(err)
}

failpoint.Inject("mockTruncateTableUpdateVersionError", func(val failpoint.Value) {
if val.(bool) {
failpoint.Return(ver, errors.New("mock update version error"))
}
})

ver, err = updateSchemaVersion(t, job)
if err != nil {
return ver, errors.Trace(err)
Expand Down