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 : support alter table xx nocache operations switch a table into uncacheable #29621

Merged
merged 12 commits into from
Nov 11, 2021
24 changes: 23 additions & 1 deletion ddl/db_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/errno"
"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/parser/terror"
"github.com/pingcap/tidb/util/testkit"
)
Expand All @@ -35,7 +36,7 @@ func (s *testDBSuite2) TestAlterTableCache(c *C) {
tk.MustGetErrCode("alter table t1 ca", errno.ErrParse)
tk.MustGetErrCode("alter table t2 cache", errno.ErrNoSuchTable)
tk.MustExec("alter table t1 cache")
checkTableCache(c, tk.Se, "test", "t1")
checkTableCacheStatus(c, tk.Se, "test", "t1", model.TableCacheStatusEnable)
tk.MustExec("drop table if exists t1")
/*Test can't skip schema checker*/
tk.MustExec("drop table if exists t1,t2")
Expand Down Expand Up @@ -110,3 +111,24 @@ func (s *testDBSuite2) TestAlterViewTableCache(c *C) {
tk.MustExec("create view v as select * from cache_view_t")
tk.MustGetErrCode("alter table v cache", errno.ErrWrongObject)
}

func (s *testDBSuite2) TestAlterTableNoCache(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists nocache_t1")
/* Test of cache table */
tk.MustExec("create table nocache_t1 ( n int auto_increment primary key)")
tk.MustExec("alter table nocache_t1 cache")
checkTableCacheStatus(c, tk.Se, "test", "nocache_t1", model.TableCacheStatusEnable)
tk.MustExec("alter table nocache_t1 nocache")
checkTableCacheStatus(c, tk.Se, "test", "nocache_t1", model.TableCacheStatusDisable)
tk.MustExec("drop table if exists t1")
// Test if a table is not exists
tk.MustExec("drop table if exists nocache_t")
tk.MustGetErrCode("alter table nocache_t cache", errno.ErrNoSuchTable)
tk.MustExec("create table nocache_t (a int)")
tk.MustExec("alter table nocache_t nocache")
// Multiple no alter cache is okay
tk.MustExec("alter table nocache_t nocache")
tk.MustExec("alter table nocache_t nocache")
}
6 changes: 4 additions & 2 deletions ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6391,13 +6391,15 @@ func checkTableLock(c *C, se session.Session, dbName, tableName string, lockTp m
c.Assert(tb.Meta().Lock, IsNil)
}
}
func checkTableCache(c *C, se session.Session, dbName, tableName string) {

func checkTableCacheStatus(c *C, se session.Session, dbName, tableName string, status model.TableCacheStatusType) {
tb := testGetTableByName(c, se, dbName, tableName)
dom := domain.GetDomain(se)
err := dom.Reload()
c.Assert(err, IsNil)
c.Assert(tb.Meta().TableCacheStatusType, Equals, model.TableCacheStatusEnable)
c.Assert(tb.Meta().TableCacheStatusType, Equals, status)
}

func (s *testDBSuite2) TestDDLWithInvalidTableInfo(c *C) {
tk := testkit.NewTestKit(c, s.store)

Expand Down
27 changes: 27 additions & 0 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2857,6 +2857,8 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, ident ast
err = d.AlterTablePartitionOptions(sctx, ident, spec)
case ast.AlterTableCache:
err = d.AlterTableCache(sctx, ident)
case ast.AlterTableNoCache:
err = d.AlterTableNoCache(sctx, ident)
default:
// Nothing to do now.
}
Expand Down Expand Up @@ -6568,6 +6570,7 @@ func (d *ddl) AlterPlacementPolicy(ctx sessionctx.Context, stmt *ast.AlterPlacem
err = d.callHookOnChanged(err)
return errors.Trace(err)
}

func (d *ddl) AlterTableCache(ctx sessionctx.Context, ti ast.Ident) (err error) {
schema, t, err := d.getSchemaAndTableByIdent(ctx, ti)
if err != nil {
Expand Down Expand Up @@ -6598,3 +6601,27 @@ func (d *ddl) AlterTableCache(ctx sessionctx.Context, ti ast.Ident) (err error)
err = d.callHookOnChanged(err)
return errors.Trace(err)
}

func (d *ddl) AlterTableNoCache(ctx sessionctx.Context, ti ast.Ident) (err error) {
schema, t, err := d.getSchemaAndTableByIdent(ctx, ti)
if err != nil {
return err
}
// if a table is not in cache state, return directly
if t.Meta().TableCacheStatusType == model.TableCacheStatusDisable {
return nil
}

job := &model.Job{
SchemaID: schema.ID,
SchemaName: schema.Name.L,
TableID: t.Meta().ID,
Type: model.ActionAlterNoCacheTable,
BinlogInfo: &model.HistoryInfo{},
Args: []interface{}{},
}

err = d.doDDLJob(ctx, job)
err = d.callHookOnChanged(err)
return errors.Trace(err)
}
2 changes: 2 additions & 0 deletions ddl/ddl_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,8 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64,
ver, err = onAlterTablePlacement(d, t, job)
case model.ActionAlterCacheTable:
ver, err = onAlterCacheTable(t, job)
case model.ActionAlterNoCacheTable:
ver, err = onAlterNoCacheTable(t, job)
default:
// Invalid job, cancel it.
job.State = model.JobStateCancelled
Expand Down
36 changes: 36 additions & 0 deletions ddl/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -1477,6 +1477,7 @@ func updateLabelRules(job *model.Job, tblInfo *model.TableInfo, oldRules map[str
patch := label.NewRulePatch(newRules, oldRuleIDs)
return infosync.UpdateLabelRules(context.TODO(), patch)
}

func onAlterCacheTable(t *meta.Meta, job *model.Job) (ver int64, err error) {
tbInfo, err := getTableInfoAndCancelFaultJob(t, job, job.SchemaID)
if err != nil {
Expand Down Expand Up @@ -1519,3 +1520,38 @@ func onAlterCacheTable(t *meta.Meta, job *model.Job) (ver int64, err error) {
}
return ver, err
}

func onAlterNoCacheTable(t *meta.Meta, job *model.Job) (ver int64, err error) {
tbInfo, err := getTableInfoAndCancelFaultJob(t, job, job.SchemaID)
if err != nil {
return 0, errors.Trace(err)
}
// If the table is not in the cache state
if tbInfo.TableCacheStatusType == model.TableCacheStatusDisable {
job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tbInfo)
return ver, nil
}

switch tbInfo.TableCacheStatusType {
case model.TableCacheStatusEnable:
// enable -> switching
tbInfo.TableCacheStatusType = model.TableCacheStatusSwitching
ver, err = updateVersionAndTableInfoWithCheck(t, job, tbInfo, true)
if err != nil {
return ver, err
}
case model.TableCacheStatusSwitching:
// switching -> disable
tbInfo.TableCacheStatusType = model.TableCacheStatusDisable
ver, err = updateVersionAndTableInfoWithCheck(t, job, tbInfo, true)
if err != nil {
return ver, err
}
// Finish this job.
job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tbInfo)
default:
job.State = model.JobStateCancelled
err = ErrInvalidDDLState.GenWithStackByArgs("alter table no cache", tbInfo.TableCacheStatusType.String())
}
return ver, err
}
34 changes: 34 additions & 0 deletions ddl/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,11 @@ func (s *testTableSuite) TestTable(c *C) {
testCheckTableState(c, d, dbInfo1, tblInfo, model.StatePublic)
testCheckJobDone(c, d, job, true)
checkTableCacheTest(c, d, dbInfo1, tblInfo)
// for alter no cache table
job = testAlterNoCacheTable(c, ctx, d, dbInfo1.ID, tblInfo)
testCheckTableState(c, d, dbInfo1, tblInfo, model.StatePublic)
testCheckJobDone(c, d, job, true)
checkTableNoCacheTest(c, d, dbInfo1, tblInfo)
}

func checkTableCacheTest(c *C, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo) {
Expand All @@ -432,6 +437,18 @@ func checkTableCacheTest(c *C, d *ddl, dbInfo *model.DBInfo, tblInfo *model.Tabl
c.Assert(err, IsNil)
}

func checkTableNoCacheTest(c *C, d *ddl, dbInfo *model.DBInfo, tblInfo *model.TableInfo) {
err := kv.RunInNewTxn(context.Background(), d.store, false, func(ctx context.Context, txn kv.Transaction) error {
t := meta.NewMeta(txn)
info, err := t.GetTable(dbInfo.ID, tblInfo.ID)
c.Assert(err, IsNil)
c.Assert(info, NotNil)
c.Assert(info.TableCacheStatusType, Equals, model.TableCacheStatusDisable)
return nil
})
c.Assert(err, IsNil)
}

func testAlterCacheTable(c *C, ctx sessionctx.Context, d *ddl, newSchemaID int64, tblInfo *model.TableInfo) *model.Job {

job := &model.Job{
Expand All @@ -449,6 +466,23 @@ func testAlterCacheTable(c *C, ctx sessionctx.Context, d *ddl, newSchemaID int64
return job
}

func testAlterNoCacheTable(c *C, ctx sessionctx.Context, d *ddl, newSchemaID int64, tblInfo *model.TableInfo) *model.Job {

job := &model.Job{
SchemaID: newSchemaID,
TableID: tblInfo.ID,
Type: model.ActionAlterNoCacheTable,
BinlogInfo: &model.HistoryInfo{},
Args: []interface{}{},
}
err := d.doDDLJob(ctx, job)
c.Assert(err, IsNil)

v := getSchemaVer(c, ctx)
checkHistoryJobArgs(c, ctx, job.ID, &historyJobArgs{ver: v})
return job
}

// for drop indexes
func createTestTableForDropIndexes(c *C, ctx sessionctx.Context, d *ddl, dbInfo *model.DBInfo, name string, num int) *model.TableInfo {
tableInfo := testTableInfo(c, d, name, num)
Expand Down
1 change: 1 addition & 0 deletions parser/model/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const (
ActionAlterTablePlacement ActionType = 56
ActionAlterCacheTable ActionType = 57
ActionAlterTableStatsOptions ActionType = 58
ActionAlterNoCacheTable ActionType = 59
)

var actionMap = map[ActionType]string{
Expand Down