Skip to content

Commit

Permalink
fix: optimize show open tables xxx statment (#676) (#825)
Browse files Browse the repository at this point in the history
* fix: optimize show open tables xxx statment (#676)

* fix: convert english comments (#676)

* fix: fix bug can't match any group (#676)
  • Loading branch information
gufengwyx8 authored Apr 11, 2024
1 parent a27c47b commit 325824e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 21 deletions.
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)
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
}

0 comments on commit 325824e

Please sign in to comment.