From c745300999e7077d76dd65100e66d78ca8c1a0e6 Mon Sep 17 00:00:00 2001 From: crazycs Date: Thu, 19 Mar 2020 11:32:23 +0800 Subject: [PATCH] ddl: support recover truncate table (#15398) (#15460) --- ddl/serial_test.go | 48 ++++++++++++++++++++++++++++++---------------- executor/ddl.go | 6 +++--- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/ddl/serial_test.go b/ddl/serial_test.go index 0c90f2c94f41e..feecb046f7b2a 100644 --- a/ddl/serial_test.go +++ b/ddl/serial_test.go @@ -433,17 +433,23 @@ func (s *testSerialSuite) TestRecoverTableByJobID(c *C) { tk.MustExec("insert into t_recover values (1),(2),(3)") tk.MustExec("drop table t_recover") - rs, err := tk.Exec("admin show ddl jobs") - c.Assert(err, IsNil) - rows, err := session.GetRows4Test(context.Background(), tk.Se, rs) - c.Assert(err, IsNil) - row := rows[0] - c.Assert(row.GetString(1), Equals, "test_recover") - c.Assert(row.GetString(3), Equals, "drop table") - jobID := row.GetInt64(0) + getDDLJobID := func(table, tp string) int64 { + rs, err := tk.Exec("admin show ddl jobs") + c.Assert(err, IsNil) + rows, err := session.GetRows4Test(context.Background(), tk.Se, rs) + c.Assert(err, IsNil) + for _, row := range rows { + if row.GetString(1) == table && row.GetString(3) == tp { + return row.GetInt64(0) + } + } + c.Errorf("can't find %s table of %s", tp, table) + return -1 + } + jobID := getDDLJobID("test_recover", "drop table") // if GC safe point is not exists in mysql.tidb - _, err = tk.Exec(fmt.Sprintf("recover table by job %d", jobID)) + _, err := tk.Exec(fmt.Sprintf("recover table by job %d", jobID)) c.Assert(err, NotNil) c.Assert(err.Error(), Equals, "can not get 'tikv_gc_safe_point'") // set GC safe point @@ -492,14 +498,7 @@ func (s *testSerialSuite) TestRecoverTableByJobID(c *C) { tk.MustExec("delete from t_recover where a > 1") tk.MustExec("drop table t_recover") - rs, err = tk.Exec("admin show ddl jobs") - c.Assert(err, IsNil) - rows, err = session.GetRows4Test(context.Background(), tk.Se, rs) - c.Assert(err, IsNil) - row = rows[0] - c.Assert(row.GetString(1), Equals, "test_recover") - c.Assert(row.GetString(3), Equals, "drop table") - jobID = row.GetInt64(0) + jobID = getDDLJobID("test_recover", "drop table") tk.MustExec(fmt.Sprintf("recover table by job %d", jobID)) @@ -509,6 +508,14 @@ func (s *testSerialSuite) TestRecoverTableByJobID(c *C) { tk.MustExec("insert into t_recover values (7),(8),(9)") tk.MustQuery("select * from t_recover;").Check(testkit.Rows("1", "7", "8", "9")) + // Test for recover truncate table. + tk.MustExec("truncate table t_recover") + tk.MustExec("rename table t_recover to t_recover_new") + jobID = getDDLJobID("test_recover", "truncate table") + tk.MustExec(fmt.Sprintf("recover table by job %d", jobID)) + tk.MustExec("insert into t_recover values (10)") + tk.MustQuery("select * from t_recover;").Check(testkit.Rows("1", "7", "8", "9", "10")) + gcEnable, err := gcutil.CheckGCEnable(tk.Se) c.Assert(err, IsNil) c.Assert(gcEnable, Equals, false) @@ -608,6 +615,13 @@ func (s *testSerialSuite) TestRecoverTableByTableName(c *C) { tk.MustExec("insert into t_recover values (7),(8),(9)") tk.MustQuery("select * from t_recover;").Check(testkit.Rows("1", "7", "8", "9")) + // Recover truncate table. + tk.MustExec("truncate table t_recover") + tk.MustExec("rename table t_recover to t_recover_new1") + tk.MustExec("recover table t_recover") + tk.MustExec("insert into t_recover values (10)") + tk.MustQuery("select * from t_recover;").Check(testkit.Rows("1", "7", "8", "9", "10")) + gcEnable, err := gcutil.CheckGCEnable(tk.Se) c.Assert(err, IsNil) c.Assert(gcEnable, Equals, false) diff --git a/executor/ddl.go b/executor/ddl.go index bb3fae612db45..5116e1e7396cb 100644 --- a/executor/ddl.go +++ b/executor/ddl.go @@ -377,8 +377,8 @@ func (e *DDLExec) getRecoverTableByJobID(s *ast.RecoverTableStmt, t *meta.Meta, if job == nil { return nil, nil, admin.ErrDDLJobNotFound.GenWithStackByArgs(s.JobID) } - if job.Type != model.ActionDropTable { - return nil, nil, errors.Errorf("Job %v type is %v, not drop table", job.ID, job.Type) + if job.Type != model.ActionDropTable && job.Type != model.ActionTruncateTable { + return nil, nil, errors.Errorf("Job %v type is %v, not dropped/truncated table", job.ID, job.Type) } // Check GC safe point for getting snapshot infoSchema. @@ -424,7 +424,7 @@ func (e *DDLExec) getRecoverTableByTableName(s *ast.RecoverTableStmt, t *meta.Me // TODO: only search recent `e.JobNum` DDL jobs. for i := len(jobs) - 1; i > 0; i-- { job = jobs[i] - if job.Type != model.ActionDropTable { + if job.Type != model.ActionDropTable && job.Type != model.ActionTruncateTable { continue } // Check GC safe point for getting snapshot infoSchema.