Skip to content

Commit

Permalink
*: Add SHOW PLACEMENT support for tables (#28266)
Browse files Browse the repository at this point in the history
  • Loading branch information
lcwangchao authored Sep 26, 2021
1 parent 8f61a69 commit 61ddc74
Show file tree
Hide file tree
Showing 6 changed files with 335 additions and 31 deletions.
12 changes: 6 additions & 6 deletions ddl/placement_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ func (s *testDBSuite6) TestConstraintCompatibility(c *C) {
err := tk.ExecToErr(sql)
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, ca.errmsg)
tk.MustQuery("show placement where target='POLICY x'").Check(testkit.Rows("POLICY x REGIONS=\"cn-east1,cn-east\" SCHEDULED"))
tk.MustQuery("show placement where target='POLICY x'").Check(testkit.Rows("POLICY x REGIONS=\"cn-east1,cn-east\""))
}
}
tk.MustExec("drop placement policy x")
Expand All @@ -234,20 +234,20 @@ func (s *testDBSuite6) TestAlterPlacementPolicy(c *C) {

// test for normal cases
tk.MustExec("alter placement policy x REGIONS=\"bj,sh\"")
tk.MustQuery("show placement where target='POLICY x'").Check(testkit.Rows("POLICY x REGIONS=\"bj,sh\" SCHEDULED"))
tk.MustQuery("show placement where target='POLICY x'").Check(testkit.Rows("POLICY x REGIONS=\"bj,sh\""))

tk.MustExec("alter placement policy x " +
"PRIMARY_REGION=\"bj\" " +
"REGIONS=\"sh\" " +
"SCHEDULE=\"EVEN\"")
tk.MustQuery("show placement where target='POLICY x'").Check(testkit.Rows("POLICY x PRIMARY_REGION=\"bj\" REGIONS=\"sh\" SCHEDULE=\"EVEN\" SCHEDULED"))
tk.MustQuery("show placement where target='POLICY x'").Check(testkit.Rows("POLICY x PRIMARY_REGION=\"bj\" REGIONS=\"sh\" SCHEDULE=\"EVEN\""))

tk.MustExec("alter placement policy x " +
"LEADER_CONSTRAINTS=\"[+region=us-east-1]\" " +
"FOLLOWER_CONSTRAINTS=\"[+region=us-east-2]\" " +
"FOLLOWERS=3")
tk.MustQuery("show placement where target='POLICY x'").Check(
testkit.Rows("POLICY x LEADER_CONSTRAINTS=\"[+region=us-east-1]\" FOLLOWERS=3 FOLLOWER_CONSTRAINTS=\"[+region=us-east-2]\" SCHEDULED"),
testkit.Rows("POLICY x LEADER_CONSTRAINTS=\"[+region=us-east-1]\" FOLLOWERS=3 FOLLOWER_CONSTRAINTS=\"[+region=us-east-2]\""),
)

tk.MustExec("alter placement policy x " +
Expand All @@ -257,7 +257,7 @@ func (s *testDBSuite6) TestAlterPlacementPolicy(c *C) {
"VOTERS=5 " +
"LEARNERS=3")
tk.MustQuery("show placement where target='POLICY x'").Check(
testkit.Rows("POLICY x CONSTRAINTS=\"[+disk=ssd]\" VOTERS=5 VOTER_CONSTRAINTS=\"[+region=bj]\" LEARNERS=3 LEARNER_CONSTRAINTS=\"[+region=sh]\" SCHEDULED"),
testkit.Rows("POLICY x CONSTRAINTS=\"[+disk=ssd]\" VOTERS=5 VOTER_CONSTRAINTS=\"[+region=bj]\" LEARNERS=3 LEARNER_CONSTRAINTS=\"[+region=sh]\""),
)

// test alter not exist policies
Expand Down Expand Up @@ -472,7 +472,7 @@ func (s *testDBSuite6) TestPolicyCacheAndPolicyDependencyCache(c *C) {
tk.MustExec("create placement policy x primary_region=\"r1\" regions=\"r1,r2\" schedule=\"EVEN\";")
po := testGetPolicyByName(c, tk.Se, "x", true)
c.Assert(po, NotNil)
tk.MustQuery("show placement").Check(testkit.Rows("POLICY x PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" SCHEDULE=\"EVEN\" SCHEDULED"))
tk.MustQuery("show placement").Check(testkit.Rows("POLICY x PRIMARY_REGION=\"r1\" REGIONS=\"r1,r2\" SCHEDULE=\"EVEN\""))

tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a int) placement policy \"x\"")
Expand Down
4 changes: 2 additions & 2 deletions ddl/placement_sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,8 @@ func (s *testDBSuite6) TestCreateSchemaWithPlacement(c *C) {

tk.MustExec(`CREATE PLACEMENT POLICY PolicySchemaTest LEADER_CONSTRAINTS = "[+region=nl]" FOLLOWER_CONSTRAINTS="[+region=se]" FOLLOWERS=4 LEARNER_CONSTRAINTS="[+region=be]" LEARNERS=4`)
tk.MustExec(`CREATE PLACEMENT POLICY PolicyTableTest LEADER_CONSTRAINTS = "[+region=tl]" FOLLOWER_CONSTRAINTS="[+region=tf]" FOLLOWERS=2 LEARNER_CONSTRAINTS="[+region=tle]" LEARNERS=1`)
tk.MustQuery("SHOW PLACEMENT like 'POLICY %PolicySchemaTest%'").Check(testkit.Rows("POLICY PolicySchemaTest LEADER_CONSTRAINTS=\"[+region=nl]\" FOLLOWERS=4 FOLLOWER_CONSTRAINTS=\"[+region=se]\" LEARNERS=4 LEARNER_CONSTRAINTS=\"[+region=be]\" SCHEDULED"))
tk.MustQuery("SHOW PLACEMENT like 'POLICY %PolicyTableTest%'").Check(testkit.Rows("POLICY PolicyTableTest LEADER_CONSTRAINTS=\"[+region=tl]\" FOLLOWERS=2 FOLLOWER_CONSTRAINTS=\"[+region=tf]\" LEARNERS=1 LEARNER_CONSTRAINTS=\"[+region=tle]\" SCHEDULED"))
tk.MustQuery("SHOW PLACEMENT like 'POLICY %PolicySchemaTest%'").Check(testkit.Rows("POLICY PolicySchemaTest LEADER_CONSTRAINTS=\"[+region=nl]\" FOLLOWERS=4 FOLLOWER_CONSTRAINTS=\"[+region=se]\" LEARNERS=4 LEARNER_CONSTRAINTS=\"[+region=be]\""))
tk.MustQuery("SHOW PLACEMENT like 'POLICY %PolicyTableTest%'").Check(testkit.Rows("POLICY PolicyTableTest LEADER_CONSTRAINTS=\"[+region=tl]\" FOLLOWERS=2 FOLLOWER_CONSTRAINTS=\"[+region=tf]\" LEARNERS=1 LEARNER_CONSTRAINTS=\"[+region=tle]\""))
tk.MustExec("CREATE SCHEMA SchemaPolicyPlacementTest PLACEMENT POLICY = `PolicySchemaTest`")
tk.MustQuery("SHOW CREATE SCHEMA SCHEMAPOLICYPLACEMENTTEST").Check(testkit.Rows("SchemaPolicyPlacementTest CREATE DATABASE `SchemaPolicyPlacementTest` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ PLACEMENT POLICY = `PolicySchemaTest`"))

Expand Down
2 changes: 2 additions & 0 deletions executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ func (e *ShowExec) fetchAll(ctx context.Context) error {
return e.fetchShowPlacementLabels(ctx)
case ast.ShowPlacement:
return e.fetchShowPlacement(ctx)
case ast.ShowPlacementForTable:
return e.fetchShowPlacementForTable(ctx)
}
return nil
}
Expand Down
104 changes: 101 additions & 3 deletions executor/show_placement.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import (
"sort"

"github.com/pingcap/errors"
"github.com/pingcap/parser/ast"
"github.com/pingcap/parser/model"
"github.com/pingcap/parser/mysql"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/store/helper"
"github.com/pingcap/tidb/types/json"
"github.com/pingcap/tidb/util/sqlexec"
Expand Down Expand Up @@ -128,23 +132,117 @@ func (e *ShowExec) fetchShowPlacementLabels(ctx context.Context) error {
return nil
}

func (e *ShowExec) fetchShowPlacement(_ context.Context) error {
err := e.fetchAllPlacementPolicies()
func (e *ShowExec) fetchShowPlacementForTable(_ context.Context) (err error) {
tbl, err := e.getTable()
if err != nil {
return err
}

tblInfo := tbl.Meta()
placement, err := e.getTablePlacement(tblInfo)
if err != nil {
return err
}

if placement != nil {
ident := ast.Ident{Schema: e.Table.DBInfo.Name, Name: tblInfo.Name}
e.appendRow([]interface{}{"TABLE " + ident.String(), placement.String()})
}

return nil
}

func (e *ShowExec) fetchShowPlacement(_ context.Context) error {
if err := e.fetchAllPlacementPolicies(); err != nil {
return err
}

return e.fetchAllTablePlacements()
}

func (e *ShowExec) fetchAllPlacementPolicies() error {
policies := e.is.AllPlacementPolicies()
sort.Slice(policies, func(i, j int) bool { return policies[i].Name.O < policies[j].Name.O })
for _, policy := range policies {
name := policy.Name
settings := policy.PlacementSettings
e.appendRow([]interface{}{"POLICY " + name.String(), settings.String(), "SCHEDULED"})
e.appendRow([]interface{}{"POLICY " + name.String(), settings.String()})
}

return nil
}

func (e *ShowExec) fetchAllTablePlacements() error {
checker := privilege.GetPrivilegeManager(e.ctx)
activeRoles := e.ctx.GetSessionVars().ActiveRoles

dbs := e.is.AllSchemas()
sort.Slice(dbs, func(i, j int) bool { return dbs[i].Name.O < dbs[j].Name.O })

for _, dbInfo := range dbs {
tableRowSets := make([]struct {
name string
rows [][]interface{}
}, 0)

for _, tbl := range e.is.SchemaTables(dbInfo.Name) {
tblInfo := tbl.Meta()
if checker != nil && !checker.RequestVerification(activeRoles, dbInfo.Name.O, tblInfo.Name.O, "", mysql.AllPrivMask) {
continue
}

var rows [][]interface{}
ident := ast.Ident{Schema: dbInfo.Name, Name: tblInfo.Name}
placement, err := e.getTablePlacement(tblInfo)
if err != nil {
return err
}

if placement != nil {
rows = append(rows, []interface{}{"TABLE " + ident.String(), placement.String()})
}

// TODO: Add partition placement rules

if len(rows) > 0 {
tableRowSets = append(tableRowSets, struct {
name string
rows [][]interface{}
}{
name: tblInfo.Name.String(),
rows: rows,
})
}
}

sort.Slice(tableRowSets, func(i, j int) bool { return tableRowSets[i].name < tableRowSets[j].name })
for _, rowSet := range tableRowSets {
for _, row := range rowSet.rows {
e.appendRow(row)
}
}
}

return nil
}

func (e *ShowExec) getTablePlacement(tblInfo *model.TableInfo) (*model.PlacementSettings, error) {
placement := tblInfo.DirectPlacementOpts
if placement != nil {
return placement, nil
}

return e.getPolicyPlacement(tblInfo.PlacementPolicyRef)
}

func (e *ShowExec) getPolicyPlacement(policyRef *model.PolicyRefInfo) (settings *model.PlacementSettings, err error) {
if policyRef == nil {
return nil, nil
}

policy, ok := e.is.PolicyByName(policyRef.Name)
if !ok {
return nil, errors.Errorf("Policy with name '%s' not found", policyRef.Name)
}
return policy.PlacementSettings, nil
}
Loading

0 comments on commit 61ddc74

Please sign in to comment.