From 23654df7db2486afda6a8d58b5d4a62157982690 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Thu, 3 Aug 2023 16:22:09 +0800 Subject: [PATCH] ddl: cancel `create view` job , when failed to drop old view (#40353) (#40671) close pingcap/tidb#40352 --- ddl/table.go | 1 + ddl/table_test.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/ddl/table.go b/ddl/table.go index c42822663c618..8f974a4b075b2 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -302,6 +302,7 @@ func onCreateView(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, _ error) if oldTbInfoID > 0 && orReplace { err = t.DropTableOrView(schemaID, oldTbInfoID) if err != nil { + job.State = model.JobStateCancelled return ver, errors.Trace(err) } err = t.GetAutoIDAccessors(schemaID, oldTbInfoID).Del() diff --git a/ddl/table_test.go b/ddl/table_test.go index 08495175ec82b..9d990fc217243 100644 --- a/ddl/table_test.go +++ b/ddl/table_test.go @@ -238,6 +238,79 @@ func TestTable(t *testing.T) { testDropSchema(t, testkit.NewTestKit(t, store).Session(), d, dbInfo) } +func TestCreateView(t *testing.T) { + store, domain := testkit.CreateMockStoreAndDomainWithSchemaLease(t, testLease) + + d := domain.DDL() + dbInfo, err := testSchemaInfo(store, "test_table") + require.NoError(t, err) + testCreateSchema(t, testkit.NewTestKit(t, store).Session(), domain.DDL(), dbInfo) + + ctx := testkit.NewTestKit(t, store).Session() + + tblInfo, err := testTableInfo(store, "t", 3) + require.NoError(t, err) + job := testCreateTable(t, ctx, d, dbInfo, tblInfo) + testCheckTableState(t, store, dbInfo, tblInfo, model.StatePublic) + testCheckJobDone(t, store, job.ID, true) + + // Create a view + newTblInfo0, err := testTableInfo(store, "v", 3) + require.NoError(t, err) + job = &model.Job{ + SchemaID: dbInfo.ID, + TableID: tblInfo.ID, + Type: model.ActionCreateView, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{newTblInfo0}, + } + ctx.SetValue(sessionctx.QueryString, "skip") + err = d.DoDDLJob(ctx, job) + require.NoError(t, err) + + v := getSchemaVer(t, ctx) + tblInfo.State = model.StatePublic + checkHistoryJobArgs(t, ctx, job.ID, &historyJobArgs{ver: v, tbl: newTblInfo0}) + tblInfo.State = model.StateNone + testCheckTableState(t, store, dbInfo, tblInfo, model.StatePublic) + testCheckJobDone(t, store, job.ID, true) + + // Replace a view + newTblInfo1, err := testTableInfo(store, "v", 3) + require.NoError(t, err) + job = &model.Job{ + SchemaID: dbInfo.ID, + TableID: tblInfo.ID, + Type: model.ActionCreateView, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{newTblInfo1, true, newTblInfo0.ID}, + } + ctx.SetValue(sessionctx.QueryString, "skip") + err = d.DoDDLJob(ctx, job) + require.NoError(t, err) + + v = getSchemaVer(t, ctx) + tblInfo.State = model.StatePublic + checkHistoryJobArgs(t, ctx, job.ID, &historyJobArgs{ver: v, tbl: newTblInfo1}) + tblInfo.State = model.StateNone + testCheckTableState(t, store, dbInfo, tblInfo, model.StatePublic) + testCheckJobDone(t, store, job.ID, true) + + // Replace a view with a non-existing table id + newTblInfo2, err := testTableInfo(store, "v", 3) + require.NoError(t, err) + job = &model.Job{ + SchemaID: dbInfo.ID, + TableID: tblInfo.ID, + Type: model.ActionCreateView, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{newTblInfo2, true, newTblInfo0.ID}, + } + ctx.SetValue(sessionctx.QueryString, "skip") + err = d.DoDDLJob(ctx, job) + require.Error(t, err) +} + func checkTableCacheTest(t *testing.T, store kv.Storage, dbInfo *model.DBInfo, tblInfo *model.TableInfo) { ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnDDL) require.NoError(t, kv.RunInNewTxn(ctx, store, false, func(ctx context.Context, txn kv.Transaction) error {