Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: optimize show open tables xxx statment (#676) #825

Merged
merged 3 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pkg/mysql/thead/thead.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ var (
Col{Name: "expr", FieldType: consts.FieldTypeVarString},
Col{Name: "step", FieldType: consts.FieldTypeVarString},
}

OpenTables = Thead{
Col{Name: "Database", FieldType: consts.FieldTypeVarString},
Col{Name: "Table", FieldType: consts.FieldTypeVarString},
Col{Name: "In_use", FieldType: consts.FieldTypeInt24},
Col{Name: "Name_locked", FieldType: consts.FieldTypeInt24},
}
)

type Col struct {
Expand Down
4 changes: 4 additions & 0 deletions pkg/runtime/ast/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ type BaseShow struct {
filter interface{} // ExpressionNode or string
}

func NewBaseShow(filter string) BaseShow {
return BaseShow{filter: filter}
}

func (bs *BaseShow) Restore(flag RestoreFlag, sb *strings.Builder, args *[]int) error {
switch val := bs.filter.(type) {
case string:
Expand Down
47 changes: 37 additions & 10 deletions pkg/runtime/optimize/dal/show_open_tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ func init() {
}

func optimizeShowOpenTables(ctx context.Context, o *optimize.Optimizer) (proto.Plan, error) {
var invertedIndex map[string]string
var invertedShards map[string]string
for logicalTable, v := range o.Rule.VTables() {
t := v.Topology()
t.Each(func(x, y int) bool {
if _, phyTable, ok := t.Render(x, y); ok {
if invertedIndex == nil {
invertedIndex = make(map[string]string)
if invertedShards == nil {
invertedShards = make(map[string]string)
}
invertedIndex[phyTable] = logicalTable
invertedShards[phyTable] = logicalTable
}
return true
})
Expand All @@ -55,19 +55,46 @@ func optimizeShowOpenTables(ctx context.Context, o *optimize.Optimizer) (proto.P

tenant := rcontext.Tenant(ctx)
clusters := security.DefaultTenantManager().GetClusters(tenant)

invertedDatabases := make(map[string]string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cap add clusters.len

Copy link
Contributor Author

@gufengwyx8 gufengwyx8 Feb 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cap add clusters.len

this cap cannot be certain at this time, it will be the sum of all dbgroups

for _, cluster := range clusters {
ns := namespace.Load(tenant, cluster)
for _, d := range ns.DBGroups() {
invertedDatabases[d] = cluster
}
}

duplicates := make(map[string]struct{})

plans := make([]proto.Plan, 0, len(clusters))
for _, cluster := range clusters {
ns := namespace.Load(tenant, cluster)
// 配置里原子库 都需要执行一次
// check every group from namespace
groups := ns.DBGroups()
for i := 0; i < len(groups); i++ {
ret := dal.NewShowOpenTablesPlan(stmt)
ret.BindArgs(o.Args)
ret.SetInvertedShards(invertedIndex)
ret.SetDatabase(groups[i])
plans = append(plans, ret)
if db, ok := stmt.Like(); !ok || db == cluster {
var ret *dal.ShowOpenTablesPlan
if ok {
// filter in cluster
show := ast.NewBaseShow(groups[i])
stmtCopy := ast.ShowOpenTables{BaseShow: &show}
ret = dal.NewShowOpenTablesPlan(&stmtCopy, duplicates, false)
} else {
// no filter
ret = dal.NewShowOpenTablesPlan(stmt, duplicates, false)
}
ret.BindArgs(o.Args)
ret.SetInvertedShards(invertedShards)
ret.SetInvertedDatabases(invertedDatabases)
ret.SetDatabase(groups[i])
plans = append(plans, ret)
}
}
}
if len(plans) == 0 {
// can't match any group
return dal.NewShowOpenTablesPlan(stmt, duplicates, true), nil
}

return &dml.CompositePlan{
Plans: plans,
Expand Down
45 changes: 34 additions & 11 deletions pkg/runtime/plan/dal/show_open_tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package dal

import (
"context"
"github.com/arana-db/arana/pkg/mysql/thead"
"strings"
)

Expand All @@ -40,16 +41,21 @@ var _ proto.Plan = (*ShowOpenTablesPlan)(nil)

type ShowOpenTablesPlan struct {
plan.BasePlan
Database string
Conn proto.DB
Stmt *ast.ShowOpenTables
invertedShards map[string]string // phy table name -> logical table name
Database string
Conn proto.DB
Stmt *ast.ShowOpenTables
invertedShards map[string]string // phy table name -> logical table name
invertedDatabases map[string]string // phy database name -> logical database name
duplicates map[string]struct{} // filter duplicates
empty bool // if can't match any group, return empty result
}

// NewShowOpenTablesPlan create ShowTables Plan
func NewShowOpenTablesPlan(stmt *ast.ShowOpenTables) *ShowOpenTablesPlan {
func NewShowOpenTablesPlan(stmt *ast.ShowOpenTables, duplicates map[string]struct{}, empty bool) *ShowOpenTablesPlan {
return &ShowOpenTablesPlan{
Stmt: stmt,
Stmt: stmt,
duplicates: duplicates,
empty: empty,
}
}

Expand All @@ -65,6 +71,10 @@ func (st *ShowOpenTablesPlan) ExecIn(ctx context.Context, conn proto.VConn) (pro
err error
)

if st.empty {
return emptyRs(), nil
}

if err = st.Stmt.Restore(ast.RestoreDefault, &sb, &indexes); err != nil {
return nil, errors.WithStack(err)
}
Expand All @@ -85,9 +95,6 @@ func (st *ShowOpenTablesPlan) ExecIn(ctx context.Context, conn proto.VConn) (pro

fields, _ := ds.Fields()

// filter duplicates
duplicates := make(map[string]struct{})

// 1. convert to logical table name
// 2. filter duplicated table name
ds = dataset.Pipe(ds,
Expand All @@ -97,6 +104,10 @@ func (st *ShowOpenTablesPlan) ExecIn(ctx context.Context, conn proto.VConn) (pro
return next, nil
}

if logicDatabaseName, ok := st.invertedDatabases[dest[0].String()]; ok {
dest[0] = proto.NewValueString(logicDatabaseName)
}

if logicalTableName, ok := st.invertedShards[dest[1].String()]; ok {
dest[1] = proto.NewValueString(logicalTableName)
}
Expand All @@ -118,20 +129,32 @@ func (st *ShowOpenTablesPlan) ExecIn(ctx context.Context, conn proto.VConn) (pro
}

tableName := vr.Values()[1].String()
if _, ok := duplicates[tableName]; ok {
if _, ok := st.duplicates[tableName]; ok {
return false
}
duplicates[tableName] = struct{}{}
st.duplicates[tableName] = struct{}{}
return true
}),
)
return resultx.New(resultx.WithDataset(ds)), nil
}

func emptyRs() proto.Result {
columns := thead.OpenTables.ToFields()
ds := &dataset.VirtualDataset{
Columns: columns,
}
return resultx.New(resultx.WithDataset(ds))
}

func (st *ShowOpenTablesPlan) SetDatabase(database string) {
st.Database = database
}

func (st *ShowOpenTablesPlan) SetInvertedShards(m map[string]string) {
st.invertedShards = m
}

func (st *ShowOpenTablesPlan) SetInvertedDatabases(m map[string]string) {
st.invertedDatabases = m
}
Loading