From 0e96e863dcac1483156105109f4bfbf52bc2dfd0 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Tue, 14 Sep 2021 08:28:51 +0800 Subject: [PATCH 01/21] support database placement option and partition placement option --- ddl/db_test.go | 17 +++ ddl/ddl.go | 2 +- ddl/ddl_api.go | 216 +++++++++++++++++++++++++++++++++- ddl/ddl_worker.go | 2 + ddl/placement_policy_test.go | 218 +++++++++++++++++++++++++++++++++++ ddl/table.go | 36 ++++++ executor/ddl.go | 14 +-- 7 files changed, 488 insertions(+), 17 deletions(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index 869cc5cb99381..1e9929230bcf4 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -242,6 +242,23 @@ func (s *testDBSuite1) TestRenameIndex(c *C) { tk.MustGetErrCode("alter table t rename key k3 to K2", errno.ErrDupKeyName) } +func testGetPartitionDefinitionsByName(c *C, ctx sessionctx.Context, db string, table string, ptName string) model.PartitionDefinition { + dom := domain.GetDomain(ctx) + // Make sure the table schema is the new schema. + err := dom.Reload() + c.Assert(err, IsNil) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) + c.Assert(tbl, NotNil) + var ptDef model.PartitionDefinition + for _, def := range tbl.Meta().Partition.Definitions { + if ptName == def.Name.L { + ptDef = def + break + } + } + return ptDef +} + func testGetTableByName(c *C, ctx sessionctx.Context, db, table string) table.Table { dom := domain.GetDomain(ctx) // Make sure the table schema is the new schema. diff --git a/ddl/ddl.go b/ddl/ddl.go index cb2f2dba92586..598052fdff605 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -93,7 +93,7 @@ var ( // DDL is responsible for updating schema in data store and maintaining in-memory InfoSchema cache. type DDL interface { - CreateSchema(ctx sessionctx.Context, name model.CIStr, charsetInfo *ast.CharsetOpt) error + CreateSchema(ctx sessionctx.Context, name model.CIStr, dbOps []*ast.DatabaseOption) error AlterSchema(ctx sessionctx.Context, stmt *ast.AlterDatabaseStmt) error DropSchema(ctx sessionctx.Context, schema model.CIStr) error CreateTable(ctx sessionctx.Context, stmt *ast.CreateTableStmt) error diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 4b47459203343..e7f9060e2fc5f 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -72,10 +72,81 @@ const ( longBlobMaxLength = 4294967295 ) -func (d *ddl) CreateSchema(ctx sessionctx.Context, schema model.CIStr, charsetInfo *ast.CharsetOpt) error { +func (d *ddl) CreateSchema(ctx sessionctx.Context, schema model.CIStr, dbOps []*ast.DatabaseOption) error { dbInfo := &model.DBInfo{Name: schema} - if charsetInfo != nil { - chs, coll, err := ResolveCharsetCollation(ast.CharsetOpt{Chs: charsetInfo.Chs, Col: charsetInfo.Col}) + var opt *ast.CharsetOpt + if len(dbOps) != 0 { + opt = &ast.CharsetOpt{} + for _, val := range dbOps { + switch val.Tp { + case ast.DatabaseOptionCharset: + opt.Chs = val.Value + case ast.DatabaseOptionCollate: + opt.Col = val.Value + case ast.DatabaseOptionPlacementPrimaryRegion: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.PrimaryRegion = val.Value + case ast.DatabaseOptionPlacementRegions: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.Regions = val.Value + case ast.DatabaseOptionPlacementFollowerCount: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.Followers = val.UintValue + case ast.DatabaseOptionPlacementVoterCount: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.Voters = val.UintValue + case ast.DatabaseOptionPlacementLearnerCount: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.Learners = val.UintValue + case ast.DatabaseOptionPlacementSchedule: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.Schedule = val.Value + case ast.DatabaseOptionPlacementConstraints: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.Constraints = val.Value + case ast.DatabaseOptionPlacementLeaderConstraints: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.LeaderConstraints = val.Value + case ast.DatabaseOptionPlacementLearnerConstraints: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.LearnerConstraints = val.Value + case ast.DatabaseOptionPlacementFollowerConstraints: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.FollowerConstraints = val.Value + case ast.DatabaseOptionPlacementVoterConstraints: + if dbInfo.DirectPlacementOpts == nil { + dbInfo.DirectPlacementOpts = &model.PlacementSettings{} + } + dbInfo.DirectPlacementOpts.VoterConstraints = val.Value + case ast.DatabaseOptionPlacementPolicy: + dbInfo.PlacementPolicyRef = &model.PolicyRefInfo{ + Name: model.NewCIStr(val.Value), + } + } + } + } + if opt != nil { + chs, coll, err := ResolveCharsetCollation(ast.CharsetOpt{Chs: opt.Chs, Col: opt.Col}) if err != nil { return errors.Trace(err) } @@ -115,6 +186,25 @@ func (d *ddl) CreateSchemaWithInfo( return errors.Trace(err) } + // Can not use both a placement policy and direct assignment. If you alter specify both in a CREATE TABLE or ALTER TABLE an error will be returned. + if dbInfo.DirectPlacementOpts != nil && dbInfo.PlacementPolicyRef != nil { + return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(dbInfo.PlacementPolicyRef.Name)) + } + if dbInfo.DirectPlacementOpts != nil { + // check the direct placement option compatibility. + if err := checkPolicyValidation(dbInfo.DirectPlacementOpts); err != nil { + return errors.Trace(err) + } + } + if dbInfo.PlacementPolicyRef != nil { + // placement policy reference will override the direct placement options. + policy, ok := ctx.GetInfoSchema().(infoschema.InfoSchema).PolicyByName(dbInfo.PlacementPolicyRef.Name) + if !ok { + return errors.Trace(infoschema.ErrPlacementPolicyNotExists.GenWithStackByArgs(dbInfo.PlacementPolicyRef.Name)) + } + dbInfo.PlacementPolicyRef.ID = policy.ID + } + // FIXME: support `tryRetainID`. genIDs, err := d.genGlobalIDs(1) if err != nil { @@ -2704,6 +2794,8 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, ident ast err = d.AlterTableAttributes(sctx, ident, spec) case ast.AlterTablePartitionAttributes: err = d.AlterTablePartitionAttributes(sctx, ident, spec) + case ast.AlterTablePartitionOptions: + err = d.AlterTablePartitionOptions(sctx, ident, spec) default: // Nothing to do now. } @@ -6298,6 +6390,124 @@ func (d *ddl) AlterTablePartitionAttributes(ctx sessionctx.Context, ident ast.Id return errors.Trace(err) } +func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) (err error) { + schema, tb, err := d.getSchemaAndTableByIdent(ctx, ident) + if err != nil { + return errors.Trace(err) + } + + meta := tb.Meta() + if meta.Partition == nil { + return errors.Trace(ErrPartitionMgmtOnNonpartitioned) + } + + partitionID, err := tables.FindPartitionByName(meta, spec.PartitionNames[0].L) + if err != nil { + return errors.Trace(err) + } + ptDef := &model.PartitionDefinition{} + if spec.Options != nil { + for _, op := range spec.Options { + switch op.Tp { + case ast.TableOptionPlacementPolicy: + ptDef.PlacementPolicyRef = &model.PolicyRefInfo{ + Name: model.NewCIStr(op.StrValue), + } + case ast.TableOptionPlacementPrimaryRegion: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.PrimaryRegion = op.StrValue + case ast.TableOptionPlacementRegions: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Regions = op.StrValue + case ast.TableOptionPlacementFollowerCount: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Followers = op.UintValue + case ast.TableOptionPlacementVoterCount: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Voters = op.UintValue + case ast.TableOptionPlacementLearnerCount: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Learners = op.UintValue + case ast.TableOptionPlacementSchedule: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Schedule = op.StrValue + case ast.TableOptionPlacementConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Constraints = op.StrValue + case ast.TableOptionPlacementLeaderConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.LeaderConstraints = op.StrValue + case ast.TableOptionPlacementLearnerConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.LearnerConstraints = op.StrValue + case ast.TableOptionPlacementFollowerConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.FollowerConstraints = op.StrValue + case ast.TableOptionPlacementVoterConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.VoterConstraints = op.StrValue + } + } + } + + // Can not use both a placement policy and direct assignment. If you alter specify both in a CREATE TABLE or ALTER TABLE an error will be returned. + if ptDef.DirectPlacementOpts != nil && ptDef.PlacementPolicyRef != nil { + return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(ptDef.PlacementPolicyRef.Name)) + } + if ptDef.DirectPlacementOpts != nil { + // check the direct placement option compatibility. + if err := checkPolicyValidation(ptDef.DirectPlacementOpts); err != nil { + return errors.Trace(err) + } + } + if ptDef.PlacementPolicyRef != nil { + // placement policy reference will override the direct placement options. + policy, ok := ctx.GetInfoSchema().(infoschema.InfoSchema).PolicyByName(ptDef.PlacementPolicyRef.Name) + if !ok { + return errors.Trace(infoschema.ErrPlacementPolicyNotExists.GenWithStackByArgs(ptDef.PlacementPolicyRef.Name)) + } + ptDef.PlacementPolicyRef.ID = policy.ID + } + job := &model.Job{ + SchemaID: schema.ID, + TableID: meta.ID, + SchemaName: schema.Name.L, + Type: model.ActionAlterTablePartitionOptions, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{partitionID, ptDef}, + } + + err = d.doDDLJob(ctx, job) + if err != nil { + return errors.Trace(err) + } + + err = d.callHookOnChanged(err) + return errors.Trace(err) +} + func buildPolicyInfo(name model.CIStr, options []*ast.PlacementOption) (*model.PolicyInfo, error) { policyInfo := &model.PolicyInfo{PlacementSettings: &model.PlacementSettings{}} policyInfo.Name = name diff --git a/ddl/ddl_worker.go b/ddl/ddl_worker.go index fb4220cc67965..c4a66ffb1edfa 100644 --- a/ddl/ddl_worker.go +++ b/ddl/ddl_worker.go @@ -832,6 +832,8 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, ver, err = onDropPlacementPolicy(d, t, job) case model.ActionAlterPlacementPolicy: ver, err = onAlterPlacementPolicy(t, job) + case model.ActionAlterTablePartitionOptions: + ver, err = onAlterTablePartitionOptions(t, job) default: // Invalid job, cancel it. job.State = model.JobStateCancelled diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index fc567ac5e49fb..68b9ee647b1f8 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -427,3 +427,221 @@ func (s *testDBSuite6) TestDropPlacementPolicyInUse(c *C) { c.Assert(err.Error(), Equals, fmt.Sprintf("[ddl:8241]Placement policy '%s' is still in use", policyName)) } } + +func (s *testDBSuite6) TestCreateDatabaseWithPlacementPolicy(c *C) { + tk := testkit.NewTestKit(c, s.store) + defer func() { + tk.MustExec("drop database if exists placementDb1") + tk.MustExec("drop placement policy if exists x") + }() + + tk.MustExec("drop database if exists placementDb1") + // Direct placement option: special constraints may be incompatible with common constraint. + _, err := tk.Exec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd,-zone=cn-east-1]\"") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") + + tk.MustExec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\"") + + db := testGetSchemaByName(c, tk.Se, "placementDb1") + c.Assert(db, NotNil) + c.Assert(db.PlacementPolicyRef, IsNil) + c.Assert(db.DirectPlacementOpts, NotNil) + + checkFunc := func(policySetting *model.PlacementSettings) { + c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") + c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") + c.Assert(policySetting.Followers, Equals, uint64(2)) + c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.Voters, Equals, uint64(0)) + c.Assert(policySetting.VoterConstraints, Equals, "") + c.Assert(policySetting.Learners, Equals, uint64(0)) + c.Assert(policySetting.LearnerConstraints, Equals, "") + c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Schedule, Equals, "") + } + checkFunc(db.DirectPlacementOpts) + tk.MustExec("drop database if exists placementDb1") + + // Direct placement option and placement policy can't co-exist. + _, err = tk.Exec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" " + + "PLACEMENT POLICY=\"x\"") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "[ddl:8240]Placement policy 'x' can't co-exist with direct placement options") + + // Only placement policy should check the policy existence. + tk.MustGetErrCode("create database placementDb1 "+ + "PLACEMENT POLICY=\"x\"", mysql.ErrPlacementPolicyNotExists) + tk.MustExec("create placement policy x " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" ") + tk.MustExec("create database placementDb1 " + + "PLACEMENT POLICY=\"x\"") + + db = testGetSchemaByName(c, tk.Se, "placementDb1") + c.Assert(db, NotNil) + c.Assert(db.PlacementPolicyRef, NotNil) + c.Assert(db.PlacementPolicyRef.Name.L, Equals, "x") + c.Assert(db.PlacementPolicyRef.ID != 0, Equals, true) + tk.MustExec("drop database if exists placementDb1") + + // Only direct placement options should check the compatibility itself. + _, err = tk.Exec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd, -zone=cn-east-1]\" ") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") + + tk.MustExec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" ") + + db = testGetSchemaByName(c, tk.Se, "placementDb1") + c.Assert(db, NotNil) + c.Assert(db.DirectPlacementOpts, NotNil) + + checkFunc = func(policySetting *model.PlacementSettings) { + c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") + c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") + c.Assert(policySetting.Followers, Equals, uint64(2)) + c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.Voters, Equals, uint64(0)) + c.Assert(policySetting.VoterConstraints, Equals, "") + c.Assert(policySetting.Learners, Equals, uint64(0)) + c.Assert(policySetting.LearnerConstraints, Equals, "") + c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Schedule, Equals, "") + } + checkFunc(db.DirectPlacementOpts) +} + +func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { + tk := testkit.NewTestKit(c, s.store) + defer func() { + tk.MustExec("drop table if exists t1") + tk.MustExec("drop placement policy if exists x") + }() + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + // Direct placement option: special constraints may be incompatible with common constraint. + tk.MustExec("create table t1 (c int) PARTITION BY RANGE (c) " + + "(PARTITION p0 VALUES LESS THAN (6)," + + "PARTITION p1 VALUES LESS THAN (11)," + + "PARTITION p2 VALUES LESS THAN (16)," + + "PARTITION p3 VALUES LESS THAN (21));") + + tk.MustExec("alter table t1 partition p0 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\"") + + tbl := testGetTableByName(c, tk.Se, "test", "t1") + c.Assert(tbl, NotNil) + ptDef := testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") + c.Assert(ptDef.PlacementPolicyRef, IsNil) + c.Assert(ptDef.DirectPlacementOpts, NotNil) + + checkFunc := func(policySetting *model.PlacementSettings) { + c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") + c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") + c.Assert(policySetting.Followers, Equals, uint64(2)) + c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.Voters, Equals, uint64(0)) + c.Assert(policySetting.VoterConstraints, Equals, "") + c.Assert(policySetting.Learners, Equals, uint64(0)) + c.Assert(policySetting.LearnerConstraints, Equals, "") + c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Schedule, Equals, "") + } + checkFunc(ptDef.DirectPlacementOpts) + + //Direct placement option and placement policy can't co-exist. + _, err := tk.Exec("alter table t1 partition p0 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" " + + "PLACEMENT POLICY=\"x\"") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "[ddl:8240]Placement policy 'x' can't co-exist with direct placement options") + + // Only placement policy should check the policy existence. + tk.MustGetErrCode("alter table t1 partition p0 "+ + "PLACEMENT POLICY=\"x\"", mysql.ErrPlacementPolicyNotExists) + tk.MustExec("create placement policy x " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" ") + tk.MustExec("alter table t1 partition p0 " + + "PLACEMENT POLICY=\"x\"") + + ptDef = testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") + c.Assert(ptDef, NotNil) + c.Assert(ptDef.PlacementPolicyRef, NotNil) + c.Assert(ptDef.PlacementPolicyRef.Name.L, Equals, "x") + c.Assert(ptDef.PlacementPolicyRef.ID != 0, Equals, true) + + // Only direct placement options should check the compatibility itself. + _, err = tk.Exec("alter table t1 partition p0 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd, -zone=cn-east-1]\" ") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") + + tk.MustExec("alter table t1 partition p0 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" ") + + ptDef = testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") + c.Assert(ptDef, NotNil) + c.Assert(ptDef.DirectPlacementOpts, NotNil) + + checkFunc = func(policySetting *model.PlacementSettings) { + c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") + c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") + c.Assert(policySetting.Followers, Equals, uint64(2)) + c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.Voters, Equals, uint64(0)) + c.Assert(policySetting.VoterConstraints, Equals, "") + c.Assert(policySetting.Learners, Equals, uint64(0)) + c.Assert(policySetting.LearnerConstraints, Equals, "") + c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Schedule, Equals, "") + } + checkFunc(ptDef.DirectPlacementOpts) +} diff --git a/ddl/table.go b/ddl/table.go index 08f99eae8a52d..48065c99949f1 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -1241,6 +1241,42 @@ func onAlterTablePartitionAttributes(t *meta.Meta, job *model.Job) (ver int64, e return ver, nil } +func onAlterTablePartitionOptions(t *meta.Meta, job *model.Job) (ver int64, err error) { + var partitionID int64 + ptDef := &model.PartitionDefinition{} + err = job.DecodeArgs(&partitionID, ptDef) + if err != nil { + job.State = model.JobStateCancelled + return 0, errors.Trace(err) + } + tblInfo, err := getTableInfoAndCancelFaultJob(t, job, job.SchemaID) + if err != nil { + return 0, err + } + + ptInfo := tblInfo.GetPartitionInfo() + if ptInfo.GetNameByID(partitionID) == "" { + job.State = model.JobStateCancelled + return 0, errors.Trace(table.ErrUnknownPartition.GenWithStackByArgs("drop?", tblInfo.Name.O)) + } + for idx, orgPtDef := range ptInfo.Definitions { + if orgPtDef.ID == partitionID { + orgPtDef.DirectPlacementOpts = ptDef.DirectPlacementOpts + orgPtDef.PlacementPolicyRef = ptDef.PlacementPolicyRef + ptInfo.Definitions[idx] = orgPtDef + break + } + } + + ver, err = updateVersionAndTableInfo(t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tblInfo) + + return ver, nil +} + func getOldLabelRules(tblInfo *model.TableInfo, oldSchemaName, oldTableName string) (string, []string, []string, map[string]*label.Rule, error) { tableRuleID := fmt.Sprintf(label.TableIDFormat, label.IDPrefix, oldSchemaName, oldTableName) oldRuleIDs := []string{tableRuleID} diff --git a/executor/ddl.go b/executor/ddl.go index 975db3aa23322..867d1cd663c1a 100644 --- a/executor/ddl.go +++ b/executor/ddl.go @@ -247,19 +247,7 @@ func (e *DDLExec) executeRenameTable(s *ast.RenameTableStmt) error { } func (e *DDLExec) executeCreateDatabase(s *ast.CreateDatabaseStmt) error { - var opt *ast.CharsetOpt - if len(s.Options) != 0 { - opt = &ast.CharsetOpt{} - for _, val := range s.Options { - switch val.Tp { - case ast.DatabaseOptionCharset: - opt.Chs = val.Value - case ast.DatabaseOptionCollate: - opt.Col = val.Value - } - } - } - err := domain.GetDomain(e.ctx).DDL().CreateSchema(e.ctx, model.NewCIStr(s.Name), opt) + err := domain.GetDomain(e.ctx).DDL().CreateSchema(e.ctx, model.NewCIStr(s.Name), s.Options) if err != nil { if infoschema.ErrDatabaseExists.Equal(err) && s.IfNotExists { err = nil From 18a937954e954234422cb8eeb979eb9082fdb5bd Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Wed, 15 Sep 2021 00:09:20 +0800 Subject: [PATCH 02/21] add parser replace --- ddl/ddl_worker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddl/ddl_worker.go b/ddl/ddl_worker.go index c4a66ffb1edfa..6dfce37b9ddf7 100644 --- a/ddl/ddl_worker.go +++ b/ddl/ddl_worker.go @@ -832,7 +832,7 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, ver, err = onDropPlacementPolicy(d, t, job) case model.ActionAlterPlacementPolicy: ver, err = onAlterPlacementPolicy(t, job) - case model.ActionAlterTablePartitionOptions: + case model.ActionAlterTablePartitionPolicy: ver, err = onAlterTablePartitionOptions(t, job) default: // Invalid job, cancel it. From 8f44cd9e004539175b53b08d5ce0b8ca8c0f2968 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Fri, 17 Sep 2021 00:10:29 +0800 Subject: [PATCH 03/21] remove part about of schema --- ddl/db_test.go | 17 ------ ddl/ddl.go | 2 +- ddl/ddl_api.go | 100 +++-------------------------------- ddl/placement_policy_test.go | 17 ++++++ executor/ddl.go | 14 ++++- go.sum | 3 ++ 6 files changed, 40 insertions(+), 113 deletions(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index 1e9929230bcf4..869cc5cb99381 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -242,23 +242,6 @@ func (s *testDBSuite1) TestRenameIndex(c *C) { tk.MustGetErrCode("alter table t rename key k3 to K2", errno.ErrDupKeyName) } -func testGetPartitionDefinitionsByName(c *C, ctx sessionctx.Context, db string, table string, ptName string) model.PartitionDefinition { - dom := domain.GetDomain(ctx) - // Make sure the table schema is the new schema. - err := dom.Reload() - c.Assert(err, IsNil) - tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) - c.Assert(tbl, NotNil) - var ptDef model.PartitionDefinition - for _, def := range tbl.Meta().Partition.Definitions { - if ptName == def.Name.L { - ptDef = def - break - } - } - return ptDef -} - func testGetTableByName(c *C, ctx sessionctx.Context, db, table string) table.Table { dom := domain.GetDomain(ctx) // Make sure the table schema is the new schema. diff --git a/ddl/ddl.go b/ddl/ddl.go index 598052fdff605..cb2f2dba92586 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -93,7 +93,7 @@ var ( // DDL is responsible for updating schema in data store and maintaining in-memory InfoSchema cache. type DDL interface { - CreateSchema(ctx sessionctx.Context, name model.CIStr, dbOps []*ast.DatabaseOption) error + CreateSchema(ctx sessionctx.Context, name model.CIStr, charsetInfo *ast.CharsetOpt) error AlterSchema(ctx sessionctx.Context, stmt *ast.AlterDatabaseStmt) error DropSchema(ctx sessionctx.Context, schema model.CIStr) error CreateTable(ctx sessionctx.Context, stmt *ast.CreateTableStmt) error diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index e7f9060e2fc5f..dc0a29a1139a1 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -72,81 +72,10 @@ const ( longBlobMaxLength = 4294967295 ) -func (d *ddl) CreateSchema(ctx sessionctx.Context, schema model.CIStr, dbOps []*ast.DatabaseOption) error { +func (d *ddl) CreateSchema(ctx sessionctx.Context, schema model.CIStr, charsetInfo *ast.CharsetOpt) error { dbInfo := &model.DBInfo{Name: schema} - var opt *ast.CharsetOpt - if len(dbOps) != 0 { - opt = &ast.CharsetOpt{} - for _, val := range dbOps { - switch val.Tp { - case ast.DatabaseOptionCharset: - opt.Chs = val.Value - case ast.DatabaseOptionCollate: - opt.Col = val.Value - case ast.DatabaseOptionPlacementPrimaryRegion: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.PrimaryRegion = val.Value - case ast.DatabaseOptionPlacementRegions: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.Regions = val.Value - case ast.DatabaseOptionPlacementFollowerCount: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.Followers = val.UintValue - case ast.DatabaseOptionPlacementVoterCount: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.Voters = val.UintValue - case ast.DatabaseOptionPlacementLearnerCount: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.Learners = val.UintValue - case ast.DatabaseOptionPlacementSchedule: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.Schedule = val.Value - case ast.DatabaseOptionPlacementConstraints: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.Constraints = val.Value - case ast.DatabaseOptionPlacementLeaderConstraints: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.LeaderConstraints = val.Value - case ast.DatabaseOptionPlacementLearnerConstraints: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.LearnerConstraints = val.Value - case ast.DatabaseOptionPlacementFollowerConstraints: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.FollowerConstraints = val.Value - case ast.DatabaseOptionPlacementVoterConstraints: - if dbInfo.DirectPlacementOpts == nil { - dbInfo.DirectPlacementOpts = &model.PlacementSettings{} - } - dbInfo.DirectPlacementOpts.VoterConstraints = val.Value - case ast.DatabaseOptionPlacementPolicy: - dbInfo.PlacementPolicyRef = &model.PolicyRefInfo{ - Name: model.NewCIStr(val.Value), - } - } - } - } - if opt != nil { - chs, coll, err := ResolveCharsetCollation(ast.CharsetOpt{Chs: opt.Chs, Col: opt.Col}) + if charsetInfo != nil { + chs, coll, err := ResolveCharsetCollation(ast.CharsetOpt{Chs: charsetInfo.Chs, Col: charsetInfo.Col}) if err != nil { return errors.Trace(err) } @@ -186,25 +115,6 @@ func (d *ddl) CreateSchemaWithInfo( return errors.Trace(err) } - // Can not use both a placement policy and direct assignment. If you alter specify both in a CREATE TABLE or ALTER TABLE an error will be returned. - if dbInfo.DirectPlacementOpts != nil && dbInfo.PlacementPolicyRef != nil { - return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(dbInfo.PlacementPolicyRef.Name)) - } - if dbInfo.DirectPlacementOpts != nil { - // check the direct placement option compatibility. - if err := checkPolicyValidation(dbInfo.DirectPlacementOpts); err != nil { - return errors.Trace(err) - } - } - if dbInfo.PlacementPolicyRef != nil { - // placement policy reference will override the direct placement options. - policy, ok := ctx.GetInfoSchema().(infoschema.InfoSchema).PolicyByName(dbInfo.PlacementPolicyRef.Name) - if !ok { - return errors.Trace(infoschema.ErrPlacementPolicyNotExists.GenWithStackByArgs(dbInfo.PlacementPolicyRef.Name)) - } - dbInfo.PlacementPolicyRef.ID = policy.ID - } - // FIXME: support `tryRetainID`. genIDs, err := d.genGlobalIDs(1) if err != nil { @@ -6468,6 +6378,8 @@ func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident ptDef.DirectPlacementOpts = &model.PlacementSettings{} } ptDef.DirectPlacementOpts.VoterConstraints = op.StrValue + default: + return errors.Trace(errors.New("unknown placement policy option")) } } } @@ -6494,7 +6406,7 @@ func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident SchemaID: schema.ID, TableID: meta.ID, SchemaName: schema.Name.L, - Type: model.ActionAlterTablePartitionOptions, + Type: model.ActionAlterTablePartitionPolicy, BinlogInfo: &model.HistoryInfo{}, Args: []interface{}{partitionID, ptDef}, } diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 68b9ee647b1f8..072f72463d241 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -645,3 +645,20 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { } checkFunc(ptDef.DirectPlacementOpts) } + +func testGetPartitionDefinitionsByName(c *C, ctx sessionctx.Context, db string, table string, ptName string) model.PartitionDefinition { + dom := domain.GetDomain(ctx) + // Make sure the table schema is the new schema. + err := dom.Reload() + c.Assert(err, IsNil) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) + c.Assert(tbl, NotNil) + var ptDef model.PartitionDefinition + for _, def := range tbl.Meta().Partition.Definitions { + if ptName == def.Name.L { + ptDef = def + break + } + } + return ptDef +} diff --git a/executor/ddl.go b/executor/ddl.go index 867d1cd663c1a..975db3aa23322 100644 --- a/executor/ddl.go +++ b/executor/ddl.go @@ -247,7 +247,19 @@ func (e *DDLExec) executeRenameTable(s *ast.RenameTableStmt) error { } func (e *DDLExec) executeCreateDatabase(s *ast.CreateDatabaseStmt) error { - err := domain.GetDomain(e.ctx).DDL().CreateSchema(e.ctx, model.NewCIStr(s.Name), s.Options) + var opt *ast.CharsetOpt + if len(s.Options) != 0 { + opt = &ast.CharsetOpt{} + for _, val := range s.Options { + switch val.Tp { + case ast.DatabaseOptionCharset: + opt.Chs = val.Value + case ast.DatabaseOptionCollate: + opt.Col = val.Value + } + } + } + err := domain.GetDomain(e.ctx).DDL().CreateSchema(e.ctx, model.NewCIStr(s.Name), opt) if err != nil { if infoschema.ErrDatabaseExists.Equal(err) && s.IfNotExists { err = nil diff --git a/go.sum b/go.sum index 9789f2aa1f2e0..06d21a8d367d3 100644 --- a/go.sum +++ b/go.sum @@ -822,6 +822,7 @@ go.uber.org/fx v1.10.0/go.mod h1:vLRicqpG/qQEzno4SYU86iCwfT95EZza+Eba0ItuxqY= go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= @@ -839,6 +840,8 @@ go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= From 483b82b09faf8870a33ce600e22fa4ba9f29214b Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Fri, 17 Sep 2021 23:17:02 +0800 Subject: [PATCH 04/21] fix --- ddl/ddl_api.go | 97 ++++++++++++++++++++++++-------------------------- ddl/table.go | 15 ++++---- 2 files changed, 55 insertions(+), 57 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index dc0a29a1139a1..1c81feb327433 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -6315,107 +6315,104 @@ func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident if err != nil { return errors.Trace(err) } - ptDef := &model.PartitionDefinition{} + var policyRefInfo *model.PolicyRefInfo + var placementSettings *model.PlacementSettings if spec.Options != nil { for _, op := range spec.Options { switch op.Tp { case ast.TableOptionPlacementPolicy: - ptDef.PlacementPolicyRef = &model.PolicyRefInfo{ + policyRefInfo = &model.PolicyRefInfo{ Name: model.NewCIStr(op.StrValue), } case ast.TableOptionPlacementPrimaryRegion: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.PrimaryRegion = op.StrValue + placementSettings.PrimaryRegion = op.StrValue case ast.TableOptionPlacementRegions: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Regions = op.StrValue + placementSettings.Regions = op.StrValue case ast.TableOptionPlacementFollowerCount: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Followers = op.UintValue + placementSettings.Followers = op.UintValue case ast.TableOptionPlacementVoterCount: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Voters = op.UintValue + placementSettings.Voters = op.UintValue case ast.TableOptionPlacementLearnerCount: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Learners = op.UintValue + placementSettings.Learners = op.UintValue case ast.TableOptionPlacementSchedule: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Schedule = op.StrValue + placementSettings.Schedule = op.StrValue case ast.TableOptionPlacementConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Constraints = op.StrValue + placementSettings.Constraints = op.StrValue case ast.TableOptionPlacementLeaderConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.LeaderConstraints = op.StrValue + placementSettings.LeaderConstraints = op.StrValue case ast.TableOptionPlacementLearnerConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.LearnerConstraints = op.StrValue + placementSettings.LearnerConstraints = op.StrValue case ast.TableOptionPlacementFollowerConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.FollowerConstraints = op.StrValue + placementSettings.FollowerConstraints = op.StrValue case ast.TableOptionPlacementVoterConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.VoterConstraints = op.StrValue + placementSettings.VoterConstraints = op.StrValue default: - return errors.Trace(errors.New("unknown placement policy option")) + return errors.Trace(errors.New("unknown partition option")) } } } // Can not use both a placement policy and direct assignment. If you alter specify both in a CREATE TABLE or ALTER TABLE an error will be returned. - if ptDef.DirectPlacementOpts != nil && ptDef.PlacementPolicyRef != nil { - return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(ptDef.PlacementPolicyRef.Name)) + if placementSettings != nil && policyRefInfo != nil { + return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(policyRefInfo.Name)) } - if ptDef.DirectPlacementOpts != nil { + if placementSettings != nil { // check the direct placement option compatibility. - if err := checkPolicyValidation(ptDef.DirectPlacementOpts); err != nil { + if err := checkPolicyValidation(placementSettings); err != nil { return errors.Trace(err) } } - if ptDef.PlacementPolicyRef != nil { - // placement policy reference will override the direct placement options. - policy, ok := ctx.GetInfoSchema().(infoschema.InfoSchema).PolicyByName(ptDef.PlacementPolicyRef.Name) + if policyRefInfo != nil { + policy, ok := ctx.GetInfoSchema().(infoschema.InfoSchema).PolicyByName(policyRefInfo.Name) if !ok { - return errors.Trace(infoschema.ErrPlacementPolicyNotExists.GenWithStackByArgs(ptDef.PlacementPolicyRef.Name)) + return errors.Trace(infoschema.ErrPlacementPolicyNotExists.GenWithStackByArgs(policyRefInfo.Name)) } - ptDef.PlacementPolicyRef.ID = policy.ID + policyRefInfo.ID = policy.ID } + job := &model.Job{ SchemaID: schema.ID, TableID: meta.ID, SchemaName: schema.Name.L, Type: model.ActionAlterTablePartitionPolicy, BinlogInfo: &model.HistoryInfo{}, - Args: []interface{}{partitionID, ptDef}, + Args: []interface{}{partitionID, policyRefInfo, placementSettings}, } err = d.doDDLJob(ctx, job) - if err != nil { - return errors.Trace(err) - } - err = d.callHookOnChanged(err) return errors.Trace(err) } diff --git a/ddl/table.go b/ddl/table.go index 48065c99949f1..8d533f7db3baf 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -1243,8 +1243,9 @@ func onAlterTablePartitionAttributes(t *meta.Meta, job *model.Job) (ver int64, e func onAlterTablePartitionOptions(t *meta.Meta, job *model.Job) (ver int64, err error) { var partitionID int64 - ptDef := &model.PartitionDefinition{} - err = job.DecodeArgs(&partitionID, ptDef) + policyRefInfo := &model.PolicyRefInfo{} + placementSettings := &model.PlacementSettings{} + err = job.DecodeArgs(&partitionID, policyRefInfo, placementSettings) if err != nil { job.State = model.JobStateCancelled return 0, errors.Trace(err) @@ -1259,11 +1260,11 @@ func onAlterTablePartitionOptions(t *meta.Meta, job *model.Job) (ver int64, err job.State = model.JobStateCancelled return 0, errors.Trace(table.ErrUnknownPartition.GenWithStackByArgs("drop?", tblInfo.Name.O)) } - for idx, orgPtDef := range ptInfo.Definitions { - if orgPtDef.ID == partitionID { - orgPtDef.DirectPlacementOpts = ptDef.DirectPlacementOpts - orgPtDef.PlacementPolicyRef = ptDef.PlacementPolicyRef - ptInfo.Definitions[idx] = orgPtDef + for idx, ptDef := range ptInfo.Definitions { + if ptDef.ID == partitionID { + ptDef.DirectPlacementOpts = placementSettings + ptDef.PlacementPolicyRef = policyRefInfo + ptInfo.Definitions[idx] = ptDef break } } From 214e69fd15ea4522b3091c7372dfe91d130eb3a1 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Wed, 22 Sep 2021 23:39:32 +0800 Subject: [PATCH 05/21] fix go.mod --- go.mod | 6 +++--- go.sum | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2269ba7af1f13..9efe2551db907 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/pingcap/fn v0.0.0-20200306044125-d5540d389059 github.com/pingcap/kvproto v0.0.0-20210806074406-317f69fb54b4 github.com/pingcap/log v0.0.0-20210906054005-afc726e70354 - github.com/pingcap/parser v0.0.0-20210915160042-658edc1dba6a + github.com/pingcap/parser v0.0.0-20210922065454-be474896cea7 github.com/pingcap/sysutil v0.0.0-20210730114356-fcd8a63f68c5 github.com/pingcap/tidb-tools v5.0.3+incompatible github.com/pingcap/tipb v0.0.0-20210802080519-94b831c6db55 @@ -75,9 +75,9 @@ require ( go.etcd.io/etcd v0.5.0-alpha.5.0.20200824191128-ae9734ed278b go.uber.org/atomic v1.9.0 go.uber.org/automaxprocs v1.4.0 - go.uber.org/goleak v1.1.10 + go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 go.uber.org/multierr v1.7.0 - go.uber.org/zap v1.19.0 + go.uber.org/zap v1.19.1 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum index 06d21a8d367d3..642df0513030e 100644 --- a/go.sum +++ b/go.sum @@ -603,6 +603,8 @@ github.com/pingcap/log v0.0.0-20210906054005-afc726e70354/go.mod h1:DWQW5jICDR7U github.com/pingcap/parser v0.0.0-20210525032559-c37778aff307/go.mod h1:xZC8I7bug4GJ5KtHhgAikjTfU4kBv1Sbo3Pf1MZ6lVw= github.com/pingcap/parser v0.0.0-20210915160042-658edc1dba6a h1:dApxKqk49ZaE/oErh4h5W27SJyyy5/oywIzpStANgLI= github.com/pingcap/parser v0.0.0-20210915160042-658edc1dba6a/go.mod h1:+xcMiiZzdIktT/Nqdfm81dkECJ2EPuoAYywd57py4Pk= +github.com/pingcap/parser v0.0.0-20210922065454-be474896cea7 h1:BQ0cLb2GUJwhuQp5YjSxPomfOOZ1IZEBhDJ1zUq/aqU= +github.com/pingcap/parser v0.0.0-20210922065454-be474896cea7/go.mod h1:+xcMiiZzdIktT/Nqdfm81dkECJ2EPuoAYywd57py4Pk= github.com/pingcap/sysutil v0.0.0-20200206130906-2bfa6dc40bcd/go.mod h1:EB/852NMQ+aRKioCpToQ94Wl7fktV+FNnxf3CX/TTXI= github.com/pingcap/sysutil v0.0.0-20210315073920-cc0985d983a3/go.mod h1:tckvA041UWP+NqYzrJ3fMgC/Hw9wnmQ/tUkp/JaHly8= github.com/pingcap/sysutil v0.0.0-20210730114356-fcd8a63f68c5 h1:7rvAtZe/ZUzOKzgriNPQoBNvleJXBk4z7L3Z47+tS98= From c7dce67f1d95b2edaaacb3717b84e077f5162ffe Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Thu, 23 Sep 2021 00:21:17 +0800 Subject: [PATCH 06/21] fix --- ddl/placement_policy_test.go | 118 +---------------------------------- go.mod | 4 +- go.sum | 3 - 3 files changed, 3 insertions(+), 122 deletions(-) diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 072f72463d241..afc81fabc68a3 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -428,117 +428,6 @@ func (s *testDBSuite6) TestDropPlacementPolicyInUse(c *C) { } } -func (s *testDBSuite6) TestCreateDatabaseWithPlacementPolicy(c *C) { - tk := testkit.NewTestKit(c, s.store) - defer func() { - tk.MustExec("drop database if exists placementDb1") - tk.MustExec("drop placement policy if exists x") - }() - - tk.MustExec("drop database if exists placementDb1") - // Direct placement option: special constraints may be incompatible with common constraint. - _, err := tk.Exec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd,-zone=cn-east-1]\"") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") - - tk.MustExec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\"") - - db := testGetSchemaByName(c, tk.Se, "placementDb1") - c.Assert(db, NotNil) - c.Assert(db.PlacementPolicyRef, IsNil) - c.Assert(db.DirectPlacementOpts, NotNil) - - checkFunc := func(policySetting *model.PlacementSettings) { - c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") - c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") - c.Assert(policySetting.Followers, Equals, uint64(2)) - c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") - c.Assert(policySetting.Voters, Equals, uint64(0)) - c.Assert(policySetting.VoterConstraints, Equals, "") - c.Assert(policySetting.Learners, Equals, uint64(0)) - c.Assert(policySetting.LearnerConstraints, Equals, "") - c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") - c.Assert(policySetting.Schedule, Equals, "") - } - checkFunc(db.DirectPlacementOpts) - tk.MustExec("drop database if exists placementDb1") - - // Direct placement option and placement policy can't co-exist. - _, err = tk.Exec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" " + - "PLACEMENT POLICY=\"x\"") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:8240]Placement policy 'x' can't co-exist with direct placement options") - - // Only placement policy should check the policy existence. - tk.MustGetErrCode("create database placementDb1 "+ - "PLACEMENT POLICY=\"x\"", mysql.ErrPlacementPolicyNotExists) - tk.MustExec("create placement policy x " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" ") - tk.MustExec("create database placementDb1 " + - "PLACEMENT POLICY=\"x\"") - - db = testGetSchemaByName(c, tk.Se, "placementDb1") - c.Assert(db, NotNil) - c.Assert(db.PlacementPolicyRef, NotNil) - c.Assert(db.PlacementPolicyRef.Name.L, Equals, "x") - c.Assert(db.PlacementPolicyRef.ID != 0, Equals, true) - tk.MustExec("drop database if exists placementDb1") - - // Only direct placement options should check the compatibility itself. - _, err = tk.Exec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd, -zone=cn-east-1]\" ") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") - - tk.MustExec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" ") - - db = testGetSchemaByName(c, tk.Se, "placementDb1") - c.Assert(db, NotNil) - c.Assert(db.DirectPlacementOpts, NotNil) - - checkFunc = func(policySetting *model.PlacementSettings) { - c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") - c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") - c.Assert(policySetting.Followers, Equals, uint64(2)) - c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") - c.Assert(policySetting.Voters, Equals, uint64(0)) - c.Assert(policySetting.VoterConstraints, Equals, "") - c.Assert(policySetting.Learners, Equals, uint64(0)) - c.Assert(policySetting.LearnerConstraints, Equals, "") - c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") - c.Assert(policySetting.Schedule, Equals, "") - } - checkFunc(db.DirectPlacementOpts) -} - func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { tk := testkit.NewTestKit(c, s.store) defer func() { @@ -595,12 +484,7 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { // Only placement policy should check the policy existence. tk.MustGetErrCode("alter table t1 partition p0 "+ "PLACEMENT POLICY=\"x\"", mysql.ErrPlacementPolicyNotExists) - tk.MustExec("create placement policy x " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" ") + tk.MustExec("create placement policy x FOLLOWERS=2 ") tk.MustExec("alter table t1 partition p0 " + "PLACEMENT POLICY=\"x\"") diff --git a/go.mod b/go.mod index 9efe2551db907..4c63ec379600f 100644 --- a/go.mod +++ b/go.mod @@ -75,9 +75,9 @@ require ( go.etcd.io/etcd v0.5.0-alpha.5.0.20200824191128-ae9734ed278b go.uber.org/atomic v1.9.0 go.uber.org/automaxprocs v1.4.0 - go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 + go.uber.org/goleak v1.1.10 go.uber.org/multierr v1.7.0 - go.uber.org/zap v1.19.1 + go.uber.org/zap v1.19.0 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum index 642df0513030e..3947406e82a12 100644 --- a/go.sum +++ b/go.sum @@ -824,7 +824,6 @@ go.uber.org/fx v1.10.0/go.mod h1:vLRicqpG/qQEzno4SYU86iCwfT95EZza+Eba0ItuxqY= go.uber.org/goleak v0.10.0/go.mod h1:VCZuO8V8mFPlL0F5J5GK1rtHV3DrFcQ1R8ryq7FK0aI= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= @@ -842,8 +841,6 @@ go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= From 457ea5fb91a1f38c37e26d1c5c5c2c0590cac32d Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Thu, 23 Sep 2021 00:51:55 +0800 Subject: [PATCH 07/21] fix --- go.sum | 2 -- 1 file changed, 2 deletions(-) diff --git a/go.sum b/go.sum index 3947406e82a12..c365568b67f9d 100644 --- a/go.sum +++ b/go.sum @@ -601,8 +601,6 @@ github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuR github.com/pingcap/log v0.0.0-20210906054005-afc726e70354 h1:SvWCbCPh1YeHd9yQLksvJYAgft6wLTY1aNG81tpyscQ= github.com/pingcap/log v0.0.0-20210906054005-afc726e70354/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= github.com/pingcap/parser v0.0.0-20210525032559-c37778aff307/go.mod h1:xZC8I7bug4GJ5KtHhgAikjTfU4kBv1Sbo3Pf1MZ6lVw= -github.com/pingcap/parser v0.0.0-20210915160042-658edc1dba6a h1:dApxKqk49ZaE/oErh4h5W27SJyyy5/oywIzpStANgLI= -github.com/pingcap/parser v0.0.0-20210915160042-658edc1dba6a/go.mod h1:+xcMiiZzdIktT/Nqdfm81dkECJ2EPuoAYywd57py4Pk= github.com/pingcap/parser v0.0.0-20210922065454-be474896cea7 h1:BQ0cLb2GUJwhuQp5YjSxPomfOOZ1IZEBhDJ1zUq/aqU= github.com/pingcap/parser v0.0.0-20210922065454-be474896cea7/go.mod h1:+xcMiiZzdIktT/Nqdfm81dkECJ2EPuoAYywd57py4Pk= github.com/pingcap/sysutil v0.0.0-20200206130906-2bfa6dc40bcd/go.mod h1:EB/852NMQ+aRKioCpToQ94Wl7fktV+FNnxf3CX/TTXI= From 0dc5a0828d6f3fbda7ae3a81d412e459b41749c3 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Thu, 23 Sep 2021 00:58:18 +0800 Subject: [PATCH 08/21] fix test --- ddl/placement_policy_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index afc81fabc68a3..852ecfd331a9c 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -536,6 +536,7 @@ func testGetPartitionDefinitionsByName(c *C, ctx sessionctx.Context, db string, err := dom.Reload() c.Assert(err, IsNil) tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) + c.Assert(err, IsNil) c.Assert(tbl, NotNil) var ptDef model.PartitionDefinition for _, def := range tbl.Meta().Partition.Definitions { From 8ad82f429994e3db154ad4df7ce49c3a133f0147 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Thu, 23 Sep 2021 01:15:50 +0800 Subject: [PATCH 09/21] fix test --- ddl/placement_policy_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 852ecfd331a9c..3d0075476c606 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -453,7 +453,7 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { tbl := testGetTableByName(c, tk.Se, "test", "t1") c.Assert(tbl, NotNil) ptDef := testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") - c.Assert(ptDef.PlacementPolicyRef, IsNil) + c.Assert(ptDef.PlacementPolicyRef.Name.L, Equals, "") c.Assert(ptDef.DirectPlacementOpts, NotNil) checkFunc := func(policySetting *model.PlacementSettings) { From 2e49d6b120d7475e440beeab6c7fafc4d5958172 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Tue, 14 Sep 2021 08:28:51 +0800 Subject: [PATCH 10/21] support database placement option and partition placement option --- ddl/db_test.go | 17 +++ ddl/ddl_api.go | 120 +++++++++++++++++++ ddl/ddl_worker.go | 2 + ddl/placement_policy_test.go | 218 +++++++++++++++++++++++++++++++++++ ddl/table.go | 36 ++++++ 5 files changed, 393 insertions(+) diff --git a/ddl/db_test.go b/ddl/db_test.go index 7e9c79df2173d..a9e6faad18e34 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -242,6 +242,23 @@ func (s *testDBSuite1) TestRenameIndex(c *C) { tk.MustGetErrCode("alter table t rename key k3 to K2", errno.ErrDupKeyName) } +func testGetPartitionDefinitionsByName(c *C, ctx sessionctx.Context, db string, table string, ptName string) model.PartitionDefinition { + dom := domain.GetDomain(ctx) + // Make sure the table schema is the new schema. + err := dom.Reload() + c.Assert(err, IsNil) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) + c.Assert(tbl, NotNil) + var ptDef model.PartitionDefinition + for _, def := range tbl.Meta().Partition.Definitions { + if ptName == def.Name.L { + ptDef = def + break + } + } + return ptDef +} + func testGetTableByName(c *C, ctx sessionctx.Context, db, table string) table.Table { dom := domain.GetDomain(ctx) // Make sure the table schema is the new schema. diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index dea62f86d36e7..6fa22cd33e9a3 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -2723,6 +2723,8 @@ func (d *ddl) AlterTable(ctx context.Context, sctx sessionctx.Context, ident ast err = d.AlterTableAttributes(sctx, ident, spec) case ast.AlterTablePartitionAttributes: err = d.AlterTablePartitionAttributes(sctx, ident, spec) + case ast.AlterTablePartitionOptions: + err = d.AlterTablePartitionOptions(sctx, ident, spec) default: // Nothing to do now. } @@ -6318,6 +6320,124 @@ func (d *ddl) AlterTablePartitionAttributes(ctx sessionctx.Context, ident ast.Id return errors.Trace(err) } +func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) (err error) { + schema, tb, err := d.getSchemaAndTableByIdent(ctx, ident) + if err != nil { + return errors.Trace(err) + } + + meta := tb.Meta() + if meta.Partition == nil { + return errors.Trace(ErrPartitionMgmtOnNonpartitioned) + } + + partitionID, err := tables.FindPartitionByName(meta, spec.PartitionNames[0].L) + if err != nil { + return errors.Trace(err) + } + ptDef := &model.PartitionDefinition{} + if spec.Options != nil { + for _, op := range spec.Options { + switch op.Tp { + case ast.TableOptionPlacementPolicy: + ptDef.PlacementPolicyRef = &model.PolicyRefInfo{ + Name: model.NewCIStr(op.StrValue), + } + case ast.TableOptionPlacementPrimaryRegion: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.PrimaryRegion = op.StrValue + case ast.TableOptionPlacementRegions: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Regions = op.StrValue + case ast.TableOptionPlacementFollowerCount: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Followers = op.UintValue + case ast.TableOptionPlacementVoterCount: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Voters = op.UintValue + case ast.TableOptionPlacementLearnerCount: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Learners = op.UintValue + case ast.TableOptionPlacementSchedule: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Schedule = op.StrValue + case ast.TableOptionPlacementConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.Constraints = op.StrValue + case ast.TableOptionPlacementLeaderConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.LeaderConstraints = op.StrValue + case ast.TableOptionPlacementLearnerConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.LearnerConstraints = op.StrValue + case ast.TableOptionPlacementFollowerConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.FollowerConstraints = op.StrValue + case ast.TableOptionPlacementVoterConstraints: + if ptDef.DirectPlacementOpts == nil { + ptDef.DirectPlacementOpts = &model.PlacementSettings{} + } + ptDef.DirectPlacementOpts.VoterConstraints = op.StrValue + } + } + } + + // Can not use both a placement policy and direct assignment. If you alter specify both in a CREATE TABLE or ALTER TABLE an error will be returned. + if ptDef.DirectPlacementOpts != nil && ptDef.PlacementPolicyRef != nil { + return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(ptDef.PlacementPolicyRef.Name)) + } + if ptDef.DirectPlacementOpts != nil { + // check the direct placement option compatibility. + if err := checkPolicyValidation(ptDef.DirectPlacementOpts); err != nil { + return errors.Trace(err) + } + } + if ptDef.PlacementPolicyRef != nil { + // placement policy reference will override the direct placement options. + policy, ok := ctx.GetInfoSchema().(infoschema.InfoSchema).PolicyByName(ptDef.PlacementPolicyRef.Name) + if !ok { + return errors.Trace(infoschema.ErrPlacementPolicyNotExists.GenWithStackByArgs(ptDef.PlacementPolicyRef.Name)) + } + ptDef.PlacementPolicyRef.ID = policy.ID + } + job := &model.Job{ + SchemaID: schema.ID, + TableID: meta.ID, + SchemaName: schema.Name.L, + Type: model.ActionAlterTablePartitionOptions, + BinlogInfo: &model.HistoryInfo{}, + Args: []interface{}{partitionID, ptDef}, + } + + err = d.doDDLJob(ctx, job) + if err != nil { + return errors.Trace(err) + } + + err = d.callHookOnChanged(err) + return errors.Trace(err) +} + func buildPolicyInfo(name model.CIStr, options []*ast.PlacementOption) (*model.PolicyInfo, error) { policyInfo := &model.PolicyInfo{PlacementSettings: &model.PlacementSettings{}} policyInfo.Name = name diff --git a/ddl/ddl_worker.go b/ddl/ddl_worker.go index a7c253b5ddbdf..6e1a2e36c491c 100644 --- a/ddl/ddl_worker.go +++ b/ddl/ddl_worker.go @@ -832,6 +832,8 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, ver, err = onDropPlacementPolicy(d, t, job) case model.ActionAlterPlacementPolicy: ver, err = onAlterPlacementPolicy(d, t, job) + case model.ActionAlterTablePartitionOptions: + ver, err = onAlterTablePartitionOptions(t, job) default: // Invalid job, cancel it. job.State = model.JobStateCancelled diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 7f4e255877832..730326eb9e3bc 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -534,3 +534,221 @@ func (s *testDBSuite6) TestPolicyCacheAndPolicyDependencyCache(c *C) { c.Assert(dependencies, NotNil) c.Assert(len(dependencies), Equals, 0) } + +func (s *testDBSuite6) TestCreateDatabaseWithPlacementPolicy(c *C) { + tk := testkit.NewTestKit(c, s.store) + defer func() { + tk.MustExec("drop database if exists placementDb1") + tk.MustExec("drop placement policy if exists x") + }() + + tk.MustExec("drop database if exists placementDb1") + // Direct placement option: special constraints may be incompatible with common constraint. + _, err := tk.Exec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd,-zone=cn-east-1]\"") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") + + tk.MustExec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\"") + + db := testGetSchemaByName(c, tk.Se, "placementDb1") + c.Assert(db, NotNil) + c.Assert(db.PlacementPolicyRef, IsNil) + c.Assert(db.DirectPlacementOpts, NotNil) + + checkFunc := func(policySetting *model.PlacementSettings) { + c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") + c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") + c.Assert(policySetting.Followers, Equals, uint64(2)) + c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.Voters, Equals, uint64(0)) + c.Assert(policySetting.VoterConstraints, Equals, "") + c.Assert(policySetting.Learners, Equals, uint64(0)) + c.Assert(policySetting.LearnerConstraints, Equals, "") + c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Schedule, Equals, "") + } + checkFunc(db.DirectPlacementOpts) + tk.MustExec("drop database if exists placementDb1") + + // Direct placement option and placement policy can't co-exist. + _, err = tk.Exec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" " + + "PLACEMENT POLICY=\"x\"") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "[ddl:8240]Placement policy 'x' can't co-exist with direct placement options") + + // Only placement policy should check the policy existence. + tk.MustGetErrCode("create database placementDb1 "+ + "PLACEMENT POLICY=\"x\"", mysql.ErrPlacementPolicyNotExists) + tk.MustExec("create placement policy x " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" ") + tk.MustExec("create database placementDb1 " + + "PLACEMENT POLICY=\"x\"") + + db = testGetSchemaByName(c, tk.Se, "placementDb1") + c.Assert(db, NotNil) + c.Assert(db.PlacementPolicyRef, NotNil) + c.Assert(db.PlacementPolicyRef.Name.L, Equals, "x") + c.Assert(db.PlacementPolicyRef.ID != 0, Equals, true) + tk.MustExec("drop database if exists placementDb1") + + // Only direct placement options should check the compatibility itself. + _, err = tk.Exec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd, -zone=cn-east-1]\" ") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") + + tk.MustExec("create database placementDb1 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" ") + + db = testGetSchemaByName(c, tk.Se, "placementDb1") + c.Assert(db, NotNil) + c.Assert(db.DirectPlacementOpts, NotNil) + + checkFunc = func(policySetting *model.PlacementSettings) { + c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") + c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") + c.Assert(policySetting.Followers, Equals, uint64(2)) + c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.Voters, Equals, uint64(0)) + c.Assert(policySetting.VoterConstraints, Equals, "") + c.Assert(policySetting.Learners, Equals, uint64(0)) + c.Assert(policySetting.LearnerConstraints, Equals, "") + c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Schedule, Equals, "") + } + checkFunc(db.DirectPlacementOpts) +} + +func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { + tk := testkit.NewTestKit(c, s.store) + defer func() { + tk.MustExec("drop table if exists t1") + tk.MustExec("drop placement policy if exists x") + }() + tk.MustExec("use test") + tk.MustExec("drop table if exists t1") + // Direct placement option: special constraints may be incompatible with common constraint. + tk.MustExec("create table t1 (c int) PARTITION BY RANGE (c) " + + "(PARTITION p0 VALUES LESS THAN (6)," + + "PARTITION p1 VALUES LESS THAN (11)," + + "PARTITION p2 VALUES LESS THAN (16)," + + "PARTITION p3 VALUES LESS THAN (21));") + + tk.MustExec("alter table t1 partition p0 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\"") + + tbl := testGetTableByName(c, tk.Se, "test", "t1") + c.Assert(tbl, NotNil) + ptDef := testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") + c.Assert(ptDef.PlacementPolicyRef, IsNil) + c.Assert(ptDef.DirectPlacementOpts, NotNil) + + checkFunc := func(policySetting *model.PlacementSettings) { + c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") + c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") + c.Assert(policySetting.Followers, Equals, uint64(2)) + c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.Voters, Equals, uint64(0)) + c.Assert(policySetting.VoterConstraints, Equals, "") + c.Assert(policySetting.Learners, Equals, uint64(0)) + c.Assert(policySetting.LearnerConstraints, Equals, "") + c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Schedule, Equals, "") + } + checkFunc(ptDef.DirectPlacementOpts) + + //Direct placement option and placement policy can't co-exist. + _, err := tk.Exec("alter table t1 partition p0 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" " + + "PLACEMENT POLICY=\"x\"") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "[ddl:8240]Placement policy 'x' can't co-exist with direct placement options") + + // Only placement policy should check the policy existence. + tk.MustGetErrCode("alter table t1 partition p0 "+ + "PLACEMENT POLICY=\"x\"", mysql.ErrPlacementPolicyNotExists) + tk.MustExec("create placement policy x " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" ") + tk.MustExec("alter table t1 partition p0 " + + "PLACEMENT POLICY=\"x\"") + + ptDef = testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") + c.Assert(ptDef, NotNil) + c.Assert(ptDef.PlacementPolicyRef, NotNil) + c.Assert(ptDef.PlacementPolicyRef.Name.L, Equals, "x") + c.Assert(ptDef.PlacementPolicyRef.ID != 0, Equals, true) + + // Only direct placement options should check the compatibility itself. + _, err = tk.Exec("alter table t1 partition p0 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd, -zone=cn-east-1]\" ") + c.Assert(err, NotNil) + c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") + + tk.MustExec("alter table t1 partition p0 " + + "PRIMARY_REGION=\"cn-east-1\" " + + "REGIONS=\"cn-east-1, cn-east-2\" " + + "FOLLOWERS=2 " + + "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + + "CONSTRAINTS=\"[+disk=ssd]\" ") + + ptDef = testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") + c.Assert(ptDef, NotNil) + c.Assert(ptDef.DirectPlacementOpts, NotNil) + + checkFunc = func(policySetting *model.PlacementSettings) { + c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") + c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") + c.Assert(policySetting.Followers, Equals, uint64(2)) + c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.Voters, Equals, uint64(0)) + c.Assert(policySetting.VoterConstraints, Equals, "") + c.Assert(policySetting.Learners, Equals, uint64(0)) + c.Assert(policySetting.LearnerConstraints, Equals, "") + c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Schedule, Equals, "") + } + checkFunc(ptDef.DirectPlacementOpts) +} diff --git a/ddl/table.go b/ddl/table.go index 507ca5b404451..569be012875c6 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -1292,6 +1292,42 @@ func onAlterTablePartitionAttributes(t *meta.Meta, job *model.Job) (ver int64, e return ver, nil } +func onAlterTablePartitionOptions(t *meta.Meta, job *model.Job) (ver int64, err error) { + var partitionID int64 + ptDef := &model.PartitionDefinition{} + err = job.DecodeArgs(&partitionID, ptDef) + if err != nil { + job.State = model.JobStateCancelled + return 0, errors.Trace(err) + } + tblInfo, err := getTableInfoAndCancelFaultJob(t, job, job.SchemaID) + if err != nil { + return 0, err + } + + ptInfo := tblInfo.GetPartitionInfo() + if ptInfo.GetNameByID(partitionID) == "" { + job.State = model.JobStateCancelled + return 0, errors.Trace(table.ErrUnknownPartition.GenWithStackByArgs("drop?", tblInfo.Name.O)) + } + for idx, orgPtDef := range ptInfo.Definitions { + if orgPtDef.ID == partitionID { + orgPtDef.DirectPlacementOpts = ptDef.DirectPlacementOpts + orgPtDef.PlacementPolicyRef = ptDef.PlacementPolicyRef + ptInfo.Definitions[idx] = orgPtDef + break + } + } + + ver, err = updateVersionAndTableInfo(t, job, tblInfo, true) + if err != nil { + return ver, errors.Trace(err) + } + job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tblInfo) + + return ver, nil +} + func getOldLabelRules(tblInfo *model.TableInfo, oldSchemaName, oldTableName string) (string, []string, []string, map[string]*label.Rule, error) { tableRuleID := fmt.Sprintf(label.TableIDFormat, label.IDPrefix, oldSchemaName, oldTableName) oldRuleIDs := []string{tableRuleID} From 62633ad327fde6dbc2d07656f9b890c7d9e6c3a2 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Wed, 15 Sep 2021 00:09:20 +0800 Subject: [PATCH 11/21] add parser replace --- ddl/ddl_worker.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ddl/ddl_worker.go b/ddl/ddl_worker.go index 6e1a2e36c491c..d8177720dc067 100644 --- a/ddl/ddl_worker.go +++ b/ddl/ddl_worker.go @@ -833,6 +833,8 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, case model.ActionAlterPlacementPolicy: ver, err = onAlterPlacementPolicy(d, t, job) case model.ActionAlterTablePartitionOptions: + ver, err = onAlterPlacementPolicy(t, job) + case model.ActionAlterTablePartitionPolicy: ver, err = onAlterTablePartitionOptions(t, job) default: // Invalid job, cancel it. From d30b80eb9591f0ad3f14fb148c091933aa0d3c7b Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Fri, 17 Sep 2021 00:10:29 +0800 Subject: [PATCH 12/21] remove part about of schema --- ddl/db_test.go | 17 ----------------- ddl/ddl_api.go | 4 +++- ddl/placement_policy_test.go | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/ddl/db_test.go b/ddl/db_test.go index a9e6faad18e34..7e9c79df2173d 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -242,23 +242,6 @@ func (s *testDBSuite1) TestRenameIndex(c *C) { tk.MustGetErrCode("alter table t rename key k3 to K2", errno.ErrDupKeyName) } -func testGetPartitionDefinitionsByName(c *C, ctx sessionctx.Context, db string, table string, ptName string) model.PartitionDefinition { - dom := domain.GetDomain(ctx) - // Make sure the table schema is the new schema. - err := dom.Reload() - c.Assert(err, IsNil) - tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) - c.Assert(tbl, NotNil) - var ptDef model.PartitionDefinition - for _, def := range tbl.Meta().Partition.Definitions { - if ptName == def.Name.L { - ptDef = def - break - } - } - return ptDef -} - func testGetTableByName(c *C, ctx sessionctx.Context, db, table string) table.Table { dom := domain.GetDomain(ctx) // Make sure the table schema is the new schema. diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 6fa22cd33e9a3..bd0b3ca8aebc5 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -6398,6 +6398,8 @@ func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident ptDef.DirectPlacementOpts = &model.PlacementSettings{} } ptDef.DirectPlacementOpts.VoterConstraints = op.StrValue + default: + return errors.Trace(errors.New("unknown placement policy option")) } } } @@ -6424,7 +6426,7 @@ func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident SchemaID: schema.ID, TableID: meta.ID, SchemaName: schema.Name.L, - Type: model.ActionAlterTablePartitionOptions, + Type: model.ActionAlterTablePartitionPolicy, BinlogInfo: &model.HistoryInfo{}, Args: []interface{}{partitionID, ptDef}, } diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 730326eb9e3bc..2a391fc654f2e 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -752,3 +752,20 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { } checkFunc(ptDef.DirectPlacementOpts) } + +func testGetPartitionDefinitionsByName(c *C, ctx sessionctx.Context, db string, table string, ptName string) model.PartitionDefinition { + dom := domain.GetDomain(ctx) + // Make sure the table schema is the new schema. + err := dom.Reload() + c.Assert(err, IsNil) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) + c.Assert(tbl, NotNil) + var ptDef model.PartitionDefinition + for _, def := range tbl.Meta().Partition.Definitions { + if ptName == def.Name.L { + ptDef = def + break + } + } + return ptDef +} From 5c3b909c5c1dddaababf1db7f13ddab3e95eff5f Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Fri, 17 Sep 2021 23:17:02 +0800 Subject: [PATCH 13/21] fix --- ddl/ddl_api.go | 97 ++++++++++++++++++++++++-------------------------- ddl/table.go | 15 ++++---- 2 files changed, 55 insertions(+), 57 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index bd0b3ca8aebc5..bd07acd2ea29d 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -6335,107 +6335,104 @@ func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident if err != nil { return errors.Trace(err) } - ptDef := &model.PartitionDefinition{} + var policyRefInfo *model.PolicyRefInfo + var placementSettings *model.PlacementSettings if spec.Options != nil { for _, op := range spec.Options { switch op.Tp { case ast.TableOptionPlacementPolicy: - ptDef.PlacementPolicyRef = &model.PolicyRefInfo{ + policyRefInfo = &model.PolicyRefInfo{ Name: model.NewCIStr(op.StrValue), } case ast.TableOptionPlacementPrimaryRegion: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.PrimaryRegion = op.StrValue + placementSettings.PrimaryRegion = op.StrValue case ast.TableOptionPlacementRegions: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Regions = op.StrValue + placementSettings.Regions = op.StrValue case ast.TableOptionPlacementFollowerCount: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Followers = op.UintValue + placementSettings.Followers = op.UintValue case ast.TableOptionPlacementVoterCount: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Voters = op.UintValue + placementSettings.Voters = op.UintValue case ast.TableOptionPlacementLearnerCount: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Learners = op.UintValue + placementSettings.Learners = op.UintValue case ast.TableOptionPlacementSchedule: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Schedule = op.StrValue + placementSettings.Schedule = op.StrValue case ast.TableOptionPlacementConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.Constraints = op.StrValue + placementSettings.Constraints = op.StrValue case ast.TableOptionPlacementLeaderConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.LeaderConstraints = op.StrValue + placementSettings.LeaderConstraints = op.StrValue case ast.TableOptionPlacementLearnerConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.LearnerConstraints = op.StrValue + placementSettings.LearnerConstraints = op.StrValue case ast.TableOptionPlacementFollowerConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.FollowerConstraints = op.StrValue + placementSettings.FollowerConstraints = op.StrValue case ast.TableOptionPlacementVoterConstraints: - if ptDef.DirectPlacementOpts == nil { - ptDef.DirectPlacementOpts = &model.PlacementSettings{} + if placementSettings == nil { + placementSettings = &model.PlacementSettings{} } - ptDef.DirectPlacementOpts.VoterConstraints = op.StrValue + placementSettings.VoterConstraints = op.StrValue default: - return errors.Trace(errors.New("unknown placement policy option")) + return errors.Trace(errors.New("unknown partition option")) } } } // Can not use both a placement policy and direct assignment. If you alter specify both in a CREATE TABLE or ALTER TABLE an error will be returned. - if ptDef.DirectPlacementOpts != nil && ptDef.PlacementPolicyRef != nil { - return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(ptDef.PlacementPolicyRef.Name)) + if placementSettings != nil && policyRefInfo != nil { + return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(policyRefInfo.Name)) } - if ptDef.DirectPlacementOpts != nil { + if placementSettings != nil { // check the direct placement option compatibility. - if err := checkPolicyValidation(ptDef.DirectPlacementOpts); err != nil { + if err := checkPolicyValidation(placementSettings); err != nil { return errors.Trace(err) } } - if ptDef.PlacementPolicyRef != nil { - // placement policy reference will override the direct placement options. - policy, ok := ctx.GetInfoSchema().(infoschema.InfoSchema).PolicyByName(ptDef.PlacementPolicyRef.Name) + if policyRefInfo != nil { + policy, ok := ctx.GetInfoSchema().(infoschema.InfoSchema).PolicyByName(policyRefInfo.Name) if !ok { - return errors.Trace(infoschema.ErrPlacementPolicyNotExists.GenWithStackByArgs(ptDef.PlacementPolicyRef.Name)) + return errors.Trace(infoschema.ErrPlacementPolicyNotExists.GenWithStackByArgs(policyRefInfo.Name)) } - ptDef.PlacementPolicyRef.ID = policy.ID + policyRefInfo.ID = policy.ID } + job := &model.Job{ SchemaID: schema.ID, TableID: meta.ID, SchemaName: schema.Name.L, Type: model.ActionAlterTablePartitionPolicy, BinlogInfo: &model.HistoryInfo{}, - Args: []interface{}{partitionID, ptDef}, + Args: []interface{}{partitionID, policyRefInfo, placementSettings}, } err = d.doDDLJob(ctx, job) - if err != nil { - return errors.Trace(err) - } - err = d.callHookOnChanged(err) return errors.Trace(err) } diff --git a/ddl/table.go b/ddl/table.go index 569be012875c6..3b1edb25d3583 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -1294,8 +1294,9 @@ func onAlterTablePartitionAttributes(t *meta.Meta, job *model.Job) (ver int64, e func onAlterTablePartitionOptions(t *meta.Meta, job *model.Job) (ver int64, err error) { var partitionID int64 - ptDef := &model.PartitionDefinition{} - err = job.DecodeArgs(&partitionID, ptDef) + policyRefInfo := &model.PolicyRefInfo{} + placementSettings := &model.PlacementSettings{} + err = job.DecodeArgs(&partitionID, policyRefInfo, placementSettings) if err != nil { job.State = model.JobStateCancelled return 0, errors.Trace(err) @@ -1310,11 +1311,11 @@ func onAlterTablePartitionOptions(t *meta.Meta, job *model.Job) (ver int64, err job.State = model.JobStateCancelled return 0, errors.Trace(table.ErrUnknownPartition.GenWithStackByArgs("drop?", tblInfo.Name.O)) } - for idx, orgPtDef := range ptInfo.Definitions { - if orgPtDef.ID == partitionID { - orgPtDef.DirectPlacementOpts = ptDef.DirectPlacementOpts - orgPtDef.PlacementPolicyRef = ptDef.PlacementPolicyRef - ptInfo.Definitions[idx] = orgPtDef + for idx, ptDef := range ptInfo.Definitions { + if ptDef.ID == partitionID { + ptDef.DirectPlacementOpts = placementSettings + ptDef.PlacementPolicyRef = policyRefInfo + ptInfo.Definitions[idx] = ptDef break } } From 1634795c16d28f6385e10a7c2449cefb5ebaf6d6 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Thu, 23 Sep 2021 00:21:17 +0800 Subject: [PATCH 14/21] fix --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 9ac6a9ab5dab2..47b99e30d99e0 100644 --- a/go.mod +++ b/go.mod @@ -75,9 +75,9 @@ require ( go.etcd.io/etcd v0.5.0-alpha.5.0.20200824191128-ae9734ed278b go.uber.org/atomic v1.9.0 go.uber.org/automaxprocs v1.4.0 - go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 + go.uber.org/goleak v1.1.10 go.uber.org/multierr v1.7.0 - go.uber.org/zap v1.19.1 + go.uber.org/zap v1.19.0 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a golang.org/x/sync v0.0.0-20210220032951-036812b2e83c From 51cb28c654c3179da86d7630240206a2fb13daba Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Thu, 23 Sep 2021 00:58:18 +0800 Subject: [PATCH 15/21] fix test --- ddl/placement_policy_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 2a391fc654f2e..2c92133bd06ce 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -759,6 +759,7 @@ func testGetPartitionDefinitionsByName(c *C, ctx sessionctx.Context, db string, err := dom.Reload() c.Assert(err, IsNil) tbl, err := dom.InfoSchema().TableByName(model.NewCIStr(db), model.NewCIStr(table)) + c.Assert(err, IsNil) c.Assert(tbl, NotNil) var ptDef model.PartitionDefinition for _, def := range tbl.Meta().Partition.Definitions { From a181da58a89775f29c07d018487ed40158d43df6 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Thu, 23 Sep 2021 01:15:50 +0800 Subject: [PATCH 16/21] fix test --- ddl/placement_policy_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 2c92133bd06ce..e30e3eb7f90c8 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -671,7 +671,7 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { tbl := testGetTableByName(c, tk.Se, "test", "t1") c.Assert(tbl, NotNil) ptDef := testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") - c.Assert(ptDef.PlacementPolicyRef, IsNil) + c.Assert(ptDef.PlacementPolicyRef.Name.L, Equals, "") c.Assert(ptDef.DirectPlacementOpts, NotNil) checkFunc := func(policySetting *model.PlacementSettings) { From 936a794541be07447fe2587c8d81e94da0287dfa Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Sun, 26 Sep 2021 23:41:51 +0800 Subject: [PATCH 17/21] fix --- ddl/ddl_worker.go | 2 - ddl/placement_policy_test.go | 117 +---------------------------------- go.mod | 6 +- go.sum | 4 +- 4 files changed, 6 insertions(+), 123 deletions(-) diff --git a/ddl/ddl_worker.go b/ddl/ddl_worker.go index d8177720dc067..004b09397374e 100644 --- a/ddl/ddl_worker.go +++ b/ddl/ddl_worker.go @@ -832,8 +832,6 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64, ver, err = onDropPlacementPolicy(d, t, job) case model.ActionAlterPlacementPolicy: ver, err = onAlterPlacementPolicy(d, t, job) - case model.ActionAlterTablePartitionOptions: - ver, err = onAlterPlacementPolicy(t, job) case model.ActionAlterTablePartitionPolicy: ver, err = onAlterTablePartitionOptions(t, job) default: diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index e30e3eb7f90c8..97aab6efa2608 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -535,117 +535,6 @@ func (s *testDBSuite6) TestPolicyCacheAndPolicyDependencyCache(c *C) { c.Assert(len(dependencies), Equals, 0) } -func (s *testDBSuite6) TestCreateDatabaseWithPlacementPolicy(c *C) { - tk := testkit.NewTestKit(c, s.store) - defer func() { - tk.MustExec("drop database if exists placementDb1") - tk.MustExec("drop placement policy if exists x") - }() - - tk.MustExec("drop database if exists placementDb1") - // Direct placement option: special constraints may be incompatible with common constraint. - _, err := tk.Exec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd,-zone=cn-east-1]\"") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") - - tk.MustExec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\"") - - db := testGetSchemaByName(c, tk.Se, "placementDb1") - c.Assert(db, NotNil) - c.Assert(db.PlacementPolicyRef, IsNil) - c.Assert(db.DirectPlacementOpts, NotNil) - - checkFunc := func(policySetting *model.PlacementSettings) { - c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") - c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") - c.Assert(policySetting.Followers, Equals, uint64(2)) - c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") - c.Assert(policySetting.Voters, Equals, uint64(0)) - c.Assert(policySetting.VoterConstraints, Equals, "") - c.Assert(policySetting.Learners, Equals, uint64(0)) - c.Assert(policySetting.LearnerConstraints, Equals, "") - c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") - c.Assert(policySetting.Schedule, Equals, "") - } - checkFunc(db.DirectPlacementOpts) - tk.MustExec("drop database if exists placementDb1") - - // Direct placement option and placement policy can't co-exist. - _, err = tk.Exec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" " + - "PLACEMENT POLICY=\"x\"") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "[ddl:8240]Placement policy 'x' can't co-exist with direct placement options") - - // Only placement policy should check the policy existence. - tk.MustGetErrCode("create database placementDb1 "+ - "PLACEMENT POLICY=\"x\"", mysql.ErrPlacementPolicyNotExists) - tk.MustExec("create placement policy x " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" ") - tk.MustExec("create database placementDb1 " + - "PLACEMENT POLICY=\"x\"") - - db = testGetSchemaByName(c, tk.Se, "placementDb1") - c.Assert(db, NotNil) - c.Assert(db.PlacementPolicyRef, NotNil) - c.Assert(db.PlacementPolicyRef.Name.L, Equals, "x") - c.Assert(db.PlacementPolicyRef.ID != 0, Equals, true) - tk.MustExec("drop database if exists placementDb1") - - // Only direct placement options should check the compatibility itself. - _, err = tk.Exec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd, -zone=cn-east-1]\" ") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") - - tk.MustExec("create database placementDb1 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" ") - - db = testGetSchemaByName(c, tk.Se, "placementDb1") - c.Assert(db, NotNil) - c.Assert(db.DirectPlacementOpts, NotNil) - - checkFunc = func(policySetting *model.PlacementSettings) { - c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") - c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") - c.Assert(policySetting.Followers, Equals, uint64(2)) - c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") - c.Assert(policySetting.Voters, Equals, uint64(0)) - c.Assert(policySetting.VoterConstraints, Equals, "") - c.Assert(policySetting.Learners, Equals, uint64(0)) - c.Assert(policySetting.LearnerConstraints, Equals, "") - c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") - c.Assert(policySetting.Schedule, Equals, "") - } - checkFunc(db.DirectPlacementOpts) -} - func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { tk := testkit.NewTestKit(c, s.store) defer func() { @@ -703,11 +592,7 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { tk.MustGetErrCode("alter table t1 partition p0 "+ "PLACEMENT POLICY=\"x\"", mysql.ErrPlacementPolicyNotExists) tk.MustExec("create placement policy x " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" ") + "FOLLOWERS=2 ") tk.MustExec("alter table t1 partition p0 " + "PLACEMENT POLICY=\"x\"") diff --git a/go.mod b/go.mod index 4c63ec379600f..1b0f9f997e6c1 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/pingcap/fn v0.0.0-20200306044125-d5540d389059 github.com/pingcap/kvproto v0.0.0-20210806074406-317f69fb54b4 github.com/pingcap/log v0.0.0-20210906054005-afc726e70354 - github.com/pingcap/parser v0.0.0-20210922065454-be474896cea7 + github.com/pingcap/parser v0.0.0-20210923132047-19e7f91ed500 github.com/pingcap/sysutil v0.0.0-20210730114356-fcd8a63f68c5 github.com/pingcap/tidb-tools v5.0.3+incompatible github.com/pingcap/tipb v0.0.0-20210802080519-94b831c6db55 @@ -75,9 +75,9 @@ require ( go.etcd.io/etcd v0.5.0-alpha.5.0.20200824191128-ae9734ed278b go.uber.org/atomic v1.9.0 go.uber.org/automaxprocs v1.4.0 - go.uber.org/goleak v1.1.10 + go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 go.uber.org/multierr v1.7.0 - go.uber.org/zap v1.19.0 + go.uber.org/zap v1.19.1 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a golang.org/x/sync v0.0.0-20210220032951-036812b2e83c diff --git a/go.sum b/go.sum index 4027ab5b4697c..94c95ee2120fd 100644 --- a/go.sum +++ b/go.sum @@ -601,8 +601,8 @@ github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuR github.com/pingcap/log v0.0.0-20210906054005-afc726e70354 h1:SvWCbCPh1YeHd9yQLksvJYAgft6wLTY1aNG81tpyscQ= github.com/pingcap/log v0.0.0-20210906054005-afc726e70354/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= github.com/pingcap/parser v0.0.0-20210525032559-c37778aff307/go.mod h1:xZC8I7bug4GJ5KtHhgAikjTfU4kBv1Sbo3Pf1MZ6lVw= -github.com/pingcap/parser v0.0.0-20210917114242-ac711116bdff h1:LiwvvutmyeSkFkdVM09mH6KK+OeDVJzX7WKy9Lf0ri0= -github.com/pingcap/parser v0.0.0-20210917114242-ac711116bdff/go.mod h1:+xcMiiZzdIktT/Nqdfm81dkECJ2EPuoAYywd57py4Pk= +github.com/pingcap/parser v0.0.0-20210923132047-19e7f91ed500 h1:xe2A/2r15+ahyAVrlindm08M3guhQdv++Mmu29nNXoY= +github.com/pingcap/parser v0.0.0-20210923132047-19e7f91ed500/go.mod h1:+xcMiiZzdIktT/Nqdfm81dkECJ2EPuoAYywd57py4Pk= github.com/pingcap/sysutil v0.0.0-20200206130906-2bfa6dc40bcd/go.mod h1:EB/852NMQ+aRKioCpToQ94Wl7fktV+FNnxf3CX/TTXI= github.com/pingcap/sysutil v0.0.0-20210315073920-cc0985d983a3/go.mod h1:tckvA041UWP+NqYzrJ3fMgC/Hw9wnmQ/tUkp/JaHly8= github.com/pingcap/sysutil v0.0.0-20210730114356-fcd8a63f68c5 h1:7rvAtZe/ZUzOKzgriNPQoBNvleJXBk4z7L3Z47+tS98= From 558c468a51f8517dd49a6edf3b9816eb2d417a29 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Tue, 28 Sep 2021 08:50:23 +0800 Subject: [PATCH 18/21] fix --- ddl/ddl_api.go | 61 +++++++------------------------------------------- 1 file changed, 8 insertions(+), 53 deletions(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index bd07acd2ea29d..17ff38d6aad4d 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -6344,68 +6344,23 @@ func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident policyRefInfo = &model.PolicyRefInfo{ Name: model.NewCIStr(op.StrValue), } - case ast.TableOptionPlacementPrimaryRegion: + case ast.TableOptionPlacementPrimaryRegion, ast.TableOptionPlacementRegions, + ast.TableOptionPlacementFollowerCount, ast.TableOptionPlacementVoterCount, + ast.TableOptionPlacementLearnerCount, ast.TableOptionPlacementSchedule, + ast.TableOptionPlacementConstraints, ast.TableOptionPlacementLeaderConstraints, + ast.TableOptionPlacementLearnerConstraints, ast.TableOptionPlacementFollowerConstraints, + ast.TableOptionPlacementVoterConstraints: if placementSettings == nil { placementSettings = &model.PlacementSettings{} } - placementSettings.PrimaryRegion = op.StrValue - case ast.TableOptionPlacementRegions: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.Regions = op.StrValue - case ast.TableOptionPlacementFollowerCount: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.Followers = op.UintValue - case ast.TableOptionPlacementVoterCount: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.Voters = op.UintValue - case ast.TableOptionPlacementLearnerCount: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.Learners = op.UintValue - case ast.TableOptionPlacementSchedule: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.Schedule = op.StrValue - case ast.TableOptionPlacementConstraints: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.Constraints = op.StrValue - case ast.TableOptionPlacementLeaderConstraints: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.LeaderConstraints = op.StrValue - case ast.TableOptionPlacementLearnerConstraints: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.LearnerConstraints = op.StrValue - case ast.TableOptionPlacementFollowerConstraints: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.FollowerConstraints = op.StrValue - case ast.TableOptionPlacementVoterConstraints: - if placementSettings == nil { - placementSettings = &model.PlacementSettings{} - } - placementSettings.VoterConstraints = op.StrValue + SetDirectPlacementOpt(placementSettings, ast.PlacementOptionType(op.Tp), op.StrValue, op.UintValue) default: return errors.Trace(errors.New("unknown partition option")) } } } - // Can not use both a placement policy and direct assignment. If you alter specify both in a CREATE TABLE or ALTER TABLE an error will be returned. + // Can not use both a placement policy and direct assignment. If you specify both in a CREATE TABLE or ALTER TABLE an error will be returned. if placementSettings != nil && policyRefInfo != nil { return errors.Trace(ErrPlacementPolicyWithDirectOption.GenWithStackByArgs(policyRefInfo.Name)) } From f65fbb9c3f2382779cd6fa36a53002a262a7e108 Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Wed, 29 Sep 2021 00:24:25 +0800 Subject: [PATCH 19/21] fix --- ddl/ddl_api.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 17ff38d6aad4d..9a4a8e464f035 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -6353,7 +6353,10 @@ func (d *ddl) AlterTablePartitionOptions(ctx sessionctx.Context, ident ast.Ident if placementSettings == nil { placementSettings = &model.PlacementSettings{} } - SetDirectPlacementOpt(placementSettings, ast.PlacementOptionType(op.Tp), op.StrValue, op.UintValue) + err = SetDirectPlacementOpt(placementSettings, ast.PlacementOptionType(op.Tp), op.StrValue, op.UintValue) + if err != nil { + return err + } default: return errors.Trace(errors.New("unknown partition option")) } From 1fc2ef0dcead23ac7ae9648e8f38ce573f3e4d2b Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Wed, 29 Sep 2021 08:11:42 +0800 Subject: [PATCH 20/21] fix --- ddl/table.go | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/ddl/table.go b/ddl/table.go index 3b1edb25d3583..b5fc58ad968f3 100644 --- a/ddl/table.go +++ b/ddl/table.go @@ -1307,18 +1307,20 @@ func onAlterTablePartitionOptions(t *meta.Meta, job *model.Job) (ver int64, err } ptInfo := tblInfo.GetPartitionInfo() - if ptInfo.GetNameByID(partitionID) == "" { - job.State = model.JobStateCancelled - return 0, errors.Trace(table.ErrUnknownPartition.GenWithStackByArgs("drop?", tblInfo.Name.O)) - } - for idx, ptDef := range ptInfo.Definitions { - if ptDef.ID == partitionID { - ptDef.DirectPlacementOpts = placementSettings - ptDef.PlacementPolicyRef = policyRefInfo - ptInfo.Definitions[idx] = ptDef + isFound := false + definitions := ptInfo.Definitions + for i := range definitions { + if partitionID == definitions[i].ID { + definitions[i].DirectPlacementOpts = placementSettings + definitions[i].PlacementPolicyRef = policyRefInfo + isFound = true break } } + if !isFound { + job.State = model.JobStateCancelled + return 0, errors.Trace(table.ErrUnknownPartition.GenWithStackByArgs("drop?", tblInfo.Name.O)) + } ver, err = updateVersionAndTableInfo(t, job, tblInfo, true) if err != nil { From 6183fab69540dfa1c5aea569a341e853fefd82ff Mon Sep 17 00:00:00 2001 From: AI-Login-is-already-taken <956308585@qq.com> Date: Sat, 2 Oct 2021 16:34:58 +0800 Subject: [PATCH 21/21] fix test --- ddl/placement_policy_test.go | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/ddl/placement_policy_test.go b/ddl/placement_policy_test.go index 35760acc635d1..48465d32a986e 100644 --- a/ddl/placement_policy_test.go +++ b/ddl/placement_policy_test.go @@ -514,9 +514,7 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { tk.MustExec("alter table t1 partition p0 " + "PRIMARY_REGION=\"cn-east-1\" " + "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\"") + "FOLLOWERS=2 ") tbl := testGetTableByName(c, tk.Se, "test", "t1") c.Assert(tbl, NotNil) @@ -528,12 +526,12 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") c.Assert(policySetting.Followers, Equals, uint64(2)) - c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.FollowerConstraints, Equals, "") c.Assert(policySetting.Voters, Equals, uint64(0)) c.Assert(policySetting.VoterConstraints, Equals, "") c.Assert(policySetting.Learners, Equals, uint64(0)) c.Assert(policySetting.LearnerConstraints, Equals, "") - c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Constraints, Equals, "") c.Assert(policySetting.Schedule, Equals, "") } checkFunc(ptDef.DirectPlacementOpts) @@ -543,8 +541,6 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { "PRIMARY_REGION=\"cn-east-1\" " + "REGIONS=\"cn-east-1, cn-east-2\" " + "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" " + "PLACEMENT POLICY=\"x\"") c.Assert(err, NotNil) c.Assert(err.Error(), Equals, "[ddl:8240]Placement policy 'x' can't co-exist with direct placement options") @@ -563,22 +559,10 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { c.Assert(ptDef.PlacementPolicyRef.Name.L, Equals, "x") c.Assert(ptDef.PlacementPolicyRef.ID != 0, Equals, true) - // Only direct placement options should check the compatibility itself. - _, err = tk.Exec("alter table t1 partition p0 " + - "PRIMARY_REGION=\"cn-east-1\" " + - "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd, -zone=cn-east-1]\" ") - c.Assert(err, NotNil) - c.Assert(err.Error(), Equals, "conflicting label constraints: '-zone=cn-east-1' and '+zone=cn-east-1'") - tk.MustExec("alter table t1 partition p0 " + "PRIMARY_REGION=\"cn-east-1\" " + "REGIONS=\"cn-east-1, cn-east-2\" " + - "FOLLOWERS=2 " + - "FOLLOWER_CONSTRAINTS=\"[+zone=cn-east-1]\" " + - "CONSTRAINTS=\"[+disk=ssd]\" ") + "FOLLOWERS=2 ") ptDef = testGetPartitionDefinitionsByName(c, tk.Se, "test", "t1", "p0") c.Assert(ptDef, NotNil) @@ -588,12 +572,12 @@ func (s *testDBSuite6) TestAlterTablePartitionWithPlacementPolicy(c *C) { c.Assert(policySetting.PrimaryRegion, Equals, "cn-east-1") c.Assert(policySetting.Regions, Equals, "cn-east-1, cn-east-2") c.Assert(policySetting.Followers, Equals, uint64(2)) - c.Assert(policySetting.FollowerConstraints, Equals, "[+zone=cn-east-1]") + c.Assert(policySetting.FollowerConstraints, Equals, "") c.Assert(policySetting.Voters, Equals, uint64(0)) c.Assert(policySetting.VoterConstraints, Equals, "") c.Assert(policySetting.Learners, Equals, uint64(0)) c.Assert(policySetting.LearnerConstraints, Equals, "") - c.Assert(policySetting.Constraints, Equals, "[+disk=ssd]") + c.Assert(policySetting.Constraints, Equals, "") c.Assert(policySetting.Schedule, Equals, "") } checkFunc(ptDef.DirectPlacementOpts)