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

planner: remove unnecessary methods in global binding handler #58350

Merged
merged 8 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 0 additions & 2 deletions pkg/bindinfo/binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ const (
Using = "using"
// deleted is the bind info's deleted status.
deleted = "deleted"
// Invalid is the bind info's invalid status.
Invalid = "invalid"
// Manual indicates the binding is created by SQL like "create binding for ...".
Manual = "manual"
// Capture indicates the binding is captured by TiDB automatically.
Expand Down
5 changes: 0 additions & 5 deletions pkg/bindinfo/capture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,11 +268,6 @@ func TestCapturePreparedStmt(t *testing.T) {

tk.MustUseIndex("select /*+ use_index(t,idx_b) */ * from t where b = 1 and c > 1", "idx_c(c)")
tk.MustExec("admin flush bindings")
tk.MustExec("admin evolve bindings")
rows = tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t` where `b` = ? and `c` > ?", rows[0][0])
require.Equal(t, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idx_c`), no_order_index(@`sel_1` `test`.`t` `idx_c`)*/ * FROM `test`.`t` WHERE `b` = ? AND `c` > ?", rows[0][1])
}

func TestCapturePlanBaselineIgnoreTiFlash(t *testing.T) {
Expand Down
98 changes: 1 addition & 97 deletions pkg/bindinfo/global_handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"context"
"fmt"
"strings"
"sync"
"sync/atomic"
"time"

Expand Down Expand Up @@ -63,12 +62,6 @@ type GlobalBindingHandle interface {
// SetGlobalBindingStatus set a Bindings's status to the storage and bind cache.
SetGlobalBindingStatus(newStatus, sqlDigest string) (ok bool, err error)

// AddInvalidGlobalBinding adds Bindings which needs to be deleted into invalidBindingCache.
AddInvalidGlobalBinding(invalidBinding Binding)

// DropInvalidGlobalBinding executes the drop Bindings tasks.
DropInvalidGlobalBinding()

// Methods for load and clear global sql bindings.

// Reset is to reset the BindHandle and clean old info.
Expand All @@ -82,9 +75,6 @@ type GlobalBindingHandle interface {

// Methods for memory control.

// Size returns the size of bind info cache.
Size() int

// SetBindingCacheCapacity reset the capacity for the bindingCache.
SetBindingCacheCapacity(capacity int64)

Expand All @@ -94,12 +84,6 @@ type GlobalBindingHandle interface {
// GetMemCapacity returns the memory capacity for the bind cache.
GetMemCapacity() (memCapacity int64)

// Clear resets the bind handle. It is only used for test.
Clear()

// FlushGlobalBindings flushes the Bindings in temp maps to storage and loads them into cache.
FlushGlobalBindings() error

// Methods for Auto Capture.

// CaptureBaselines is used to automatically capture plan baselines.
Expand All @@ -118,10 +102,6 @@ type globalBindingHandle struct {
// This value is used to avoid reload duplicated bindings from storage.
lastUpdateTime atomic.Value

// invalidBindings indicates the invalid bindings found during querying.
// A binding will be deleted from this map, after 2 bind-lease, after it is dropped from the kv.
invalidBindings *invalidBindingCache

// syncBindingSingleflight is used to synchronize the execution of `LoadFromStorageToCache` method.
syncBindingSingleflight singleflight.Group
}
Expand Down Expand Up @@ -168,7 +148,6 @@ func (h *globalBindingHandle) setCache(c FuzzyBindingCache) {
// Reset is to reset the BindHandle and clean old info.
func (h *globalBindingHandle) Reset() {
h.lastUpdateTime.Store(types.ZeroTimestamp)
h.invalidBindings = newInvalidBindingCache()
h.setCache(newFuzzyBindingCache(h.LoadBindingsFromStorage))
variable.RegisterStatistics(h)
}
Expand Down Expand Up @@ -215,7 +194,7 @@ func (h *globalBindingHandle) LoadFromStorageToCache(fullLoad bool) (err error)

metrics.BindingCacheMemUsage.Set(float64(h.GetMemUsage()))
metrics.BindingCacheMemLimit.Set(float64(h.GetMemCapacity()))
metrics.BindingCacheNumBindings.Set(float64(h.Size()))
metrics.BindingCacheNumBindings.Set(float64(len(h.getCache().GetAllBindings())))
}()

for _, row := range rows {
Expand Down Expand Up @@ -436,68 +415,6 @@ func lockBindInfoTable(sctx sessionctx.Context) error {
return err
}

// invalidBindingCache is used to store invalid bindings temporarily.
type invalidBindingCache struct {
mu sync.RWMutex
m map[string]Binding // key: sqlDigest
}

func newInvalidBindingCache() *invalidBindingCache {
return &invalidBindingCache{
m: make(map[string]Binding),
}
}

func (c *invalidBindingCache) add(binding Binding) {
c.mu.Lock()
defer c.mu.Unlock()
c.m[binding.SQLDigest] = binding
}

func (c *invalidBindingCache) getAll() Bindings {
c.mu.Lock()
defer c.mu.Unlock()
bindings := make(Bindings, 0, len(c.m))
for _, binding := range c.m {
bindings = append(bindings, binding)
}
return bindings
}

func (c *invalidBindingCache) reset() {
c.mu.Lock()
defer c.mu.Unlock()
c.m = make(map[string]Binding)
}

// DropInvalidGlobalBinding executes the drop Bindings tasks.
func (h *globalBindingHandle) DropInvalidGlobalBinding() {
defer func() {
if err := h.LoadFromStorageToCache(false); err != nil {
logutil.BindLogger().Warn("drop invalid global binding error", zap.Error(err))
}
}()

invalidBindings := h.invalidBindings.getAll()
h.invalidBindings.reset()
for _, invalidBinding := range invalidBindings {
if _, err := h.dropGlobalBinding([]string{invalidBinding.SQLDigest}); err != nil {
logutil.BindLogger().Debug("flush bind record failed", zap.Error(err))
}
}
}

// AddInvalidGlobalBinding adds Bindings which needs to be deleted into invalidBindings.
func (h *globalBindingHandle) AddInvalidGlobalBinding(invalidBinding Binding) {
h.invalidBindings.add(invalidBinding)
}

// Size returns the size of bind info cache.
func (h *globalBindingHandle) Size() int {
size := len(h.getCache().GetAllBindings())
return size
}

// MatchGlobalBinding returns the matched binding for this statement.
func (h *globalBindingHandle) MatchGlobalBinding(sctx sessionctx.Context, fuzzyDigest string, tableNames []*ast.TableName) (matchedBinding Binding, isMatched bool) {
return h.getCache().FuzzyMatchingBinding(sctx, fuzzyDigest, tableNames)
Expand Down Expand Up @@ -662,19 +579,6 @@ func (*paramMarkerChecker) Leave(in ast.Node) (ast.Node, bool) {
return in, true
}

// Clear resets the bind handle. It is only used for test.
func (h *globalBindingHandle) Clear() {
h.setCache(newFuzzyBindingCache(h.LoadBindingsFromStorage))
h.setLastUpdateTime(types.ZeroTimestamp)
h.invalidBindings.reset()
}

// FlushGlobalBindings flushes the Bindings in temp maps to storage and loads them into cache.
func (h *globalBindingHandle) FlushGlobalBindings() error {
h.DropInvalidGlobalBinding()
return h.LoadFromStorageToCache(false)
}

func (h *globalBindingHandle) callWithSCtx(wrapTxn bool, f func(sctx sessionctx.Context) error) (err error) {
resource, err := h.sPool.Get()
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions pkg/bindinfo/global_handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func TestBindParse(t *testing.T) {
bindHandle := bindinfo.NewGlobalBindingHandle(&mockSessionPool{tk.Session()})
err := bindHandle.LoadFromStorageToCache(true)
require.NoError(t, err)
require.Equal(t, 1, bindHandle.Size())
require.Equal(t, 1, len(bindHandle.GetAllGlobalBindings()))

stmt, err := parser.New().ParseOneStmt("select * from test . t", "", "")
require.NoError(t, err)
Expand Down Expand Up @@ -266,7 +266,7 @@ func TestSetBindingStatusWithoutBindingInCache(t *testing.T) {
bindinfo.Manual + "', '" + sqlDigest.String() + "', '')")
tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t` where `a` > ?', 'SELECT /*+ USE_INDEX(`t` `idx_a`)*/ * FROM `test`.`t` WHERE `a` > 10', 'test', 'enabled', '2000-01-02 09:00:00', '2000-01-02 09:00:00', '', '','" +
bindinfo.Manual + "', '" + sqlDigest.String() + "', '')")
dom.BindHandle().Clear()
dom.BindHandle().Reset()
tk.MustExec("set binding disabled for select * from t where a > 10")
tk.MustExec("admin reload bindings")
rows := tk.MustQuery("show global bindings").Rows()
Expand All @@ -281,7 +281,7 @@ func TestSetBindingStatusWithoutBindingInCache(t *testing.T) {
bindinfo.Manual + "', '" + sqlDigest.String() + "', '')")
tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t` where `a` > ?', 'SELECT * FROM `test`.`t` WHERE `a` > 10', 'test', 'disabled', '2000-01-02 09:00:00', '2000-01-02 09:00:00', '', '','" +
bindinfo.Manual + "', '" + sqlDigest.String() + "', '')")
dom.BindHandle().Clear()
dom.BindHandle().Reset()
tk.MustExec("set binding enabled for select * from t where a > 10")
tk.MustExec("admin reload bindings")
rows = tk.MustQuery("show global bindings").Rows()
Expand Down Expand Up @@ -465,7 +465,7 @@ func TestGlobalBinding(t *testing.T) {
bindHandle := bindinfo.NewGlobalBindingHandle(&mockSessionPool{tk.Session()})
err = bindHandle.LoadFromStorageToCache(true)
require.NoError(t, err)
require.Equal(t, 1, bindHandle.Size())
require.Equal(t, 1, len(bindHandle.GetAllGlobalBindings()))

_, fuzzyDigest = norm.NormalizeStmtForBinding(stmt, norm.WithFuzz(true))
binding, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), fuzzyDigest, bindinfo.CollectTableNames(stmt))
Expand All @@ -488,7 +488,7 @@ func TestGlobalBinding(t *testing.T) {
bindHandle = bindinfo.NewGlobalBindingHandle(&mockSessionPool{tk.Session()})
err = bindHandle.LoadFromStorageToCache(true)
require.NoError(t, err)
require.Equal(t, 0, bindHandle.Size())
require.Equal(t, 0, len(bindHandle.GetAllGlobalBindings()))

_, fuzzyDigest = norm.NormalizeStmtForBinding(stmt, norm.WithFuzz(true))
_, matched = dom.BindHandle().MatchGlobalBinding(tk.Session(), fuzzyDigest, bindinfo.CollectTableNames(stmt))
Expand Down
2 changes: 1 addition & 1 deletion pkg/bindinfo/internal/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
// UtilCleanBindingEnv cleans the binding environment.
func UtilCleanBindingEnv(tk *testkit.TestKit, dom *domain.Domain) {
tk.MustExec("delete from mysql.bind_info where source != 'builtin'")
dom.BindHandle().Clear()
dom.BindHandle().Reset()
}

// UtilNormalizeWithDefaultDB normalizes the SQL and returns the normalized SQL and its digest.
Expand Down
14 changes: 2 additions & 12 deletions pkg/bindinfo/tests/bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,18 +442,8 @@ func TestErrorBind(t *testing.T) {
require.NotNil(t, binding.UpdateTime)

tk.MustExec("drop index index_t on t")
rs, err := tk.Exec("select * from t where i > 10")
require.NoError(t, err)
rs.Close()

dom.BindHandle().DropInvalidGlobalBinding()

rs, err = tk.Exec("show global bindings")
require.NoError(t, err)
chk := rs.NewChunk(nil)
err = rs.Next(context.TODO(), chk)
require.NoError(t, err)
require.Equal(t, 0, chk.NumRows())
require.Equal(t, 1, len(tk.MustQuery(`show global bindings`).Rows()))
tk.MustQuery("select * from t where i > 10")
}

func TestStmtHints(t *testing.T) {
Expand Down
1 change: 0 additions & 1 deletion pkg/domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2134,7 +2134,6 @@ func (do *Domain) globalBindHandleWorkerLoop(owner owner.Manager) {
if err != nil {
logutil.BgLogger().Error("update bindinfo failed", zap.Error(err))
}
bindHandle.DropInvalidGlobalBinding()
// Get Global
optVal, err := do.GetGlobalVar(variable.TiDBCapturePlanBaseline)
if err == nil && variable.TiDBOptOn(optVal) {
Expand Down
4 changes: 1 addition & 3 deletions pkg/executor/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ func (e *SQLBindExec) Next(_ context.Context, req *chunk.Chunk) error {
return e.flushBindings()
case plannercore.OpCaptureBindings:
e.captureBindings()
case plannercore.OpEvolveBindings:
return nil // not support yet
case plannercore.OpReloadBindings:
return e.reloadBindings()
case plannercore.OpSetBindingStatus:
Expand Down Expand Up @@ -159,7 +157,7 @@ func (e *SQLBindExec) createSQLBind() error {
}

func (e *SQLBindExec) flushBindings() error {
return domain.GetDomain(e.Ctx()).BindHandle().FlushGlobalBindings()
return domain.GetDomain(e.Ctx()).BindHandle().LoadFromStorageToCache(false)
}

func (e *SQLBindExec) captureBindings() {
Expand Down
1 change: 0 additions & 1 deletion pkg/planner/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ go_library(
"//pkg/domain",
"//pkg/infoschema",
"//pkg/kv",
"//pkg/metrics",
"//pkg/parser/ast",
"//pkg/parser/model",
"//pkg/planner/cascades/old",
Expand Down
2 changes: 0 additions & 2 deletions pkg/planner/core/common_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,6 @@ const (
OpFlushBindings
// OpCaptureBindings is used to capture plan bindings.
OpCaptureBindings
// OpEvolveBindings is used to evolve plan binding.
OpEvolveBindings
// OpReloadBindings is used to reload plan binding.
OpReloadBindings
// OpSetBindingStatus is used to set binding status.
Expand Down
7 changes: 1 addition & 6 deletions pkg/planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1567,12 +1567,7 @@ func (b *PlanBuilder) buildAdmin(ctx context.Context, as *ast.AdminStmt) (base.P
case ast.AdminCaptureBindings:
return &SQLBindPlan{SQLBindOp: OpCaptureBindings}, nil
case ast.AdminEvolveBindings:
var err error
// The 'baseline evolution' only work in the test environment before the feature is GA.
if !config.CheckTableBeforeDrop {
err = errors.Errorf("Cannot enable baseline evolution feature, it is not generally available now")
}
return &SQLBindPlan{SQLBindOp: OpEvolveBindings}, err
return nil, errors.Errorf("Cannot enable baseline evolution feature, it is not generally available now")
case ast.AdminReloadBindings:
return &SQLBindPlan{SQLBindOp: OpReloadBindings}, nil
case ast.AdminReloadStatistics:
Expand Down
17 changes: 0 additions & 17 deletions pkg/planner/optimize.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/pingcap/tidb/pkg/domain"
"github.com/pingcap/tidb/pkg/infoschema"
"github.com/pingcap/tidb/pkg/kv"
"github.com/pingcap/tidb/pkg/metrics"
"github.com/pingcap/tidb/pkg/parser/ast"
"github.com/pingcap/tidb/pkg/parser/model"
"github.com/pingcap/tidb/pkg/planner/cascades/old"
Expand Down Expand Up @@ -320,8 +319,6 @@ func Optimize(ctx context.Context, sctx sessionctx.Context, node *resolve.NodeW,
}
plan, curNames, cost, err := optimize(ctx, pctx, node, is)
if err != nil {
binding.Status = bindinfo.Invalid
handleInvalidBinding(ctx, pctx, scope, binding)
continue
}
if cost < minCost {
Expand Down Expand Up @@ -585,20 +582,6 @@ func buildLogicalPlan(ctx context.Context, sctx planctx.PlanContext, node *resol
return p, nil
}

func handleInvalidBinding(ctx context.Context, sctx planctx.PlanContext, level string, binding bindinfo.Binding) {
sessionHandle := sctx.Value(bindinfo.SessionBindInfoKeyType).(bindinfo.SessionBindingHandle)
err := sessionHandle.DropSessionBinding([]string{binding.SQLDigest})
if err != nil {
logutil.Logger(ctx).Info("drop session bindings failed")
}
if level == metrics.ScopeSession {
return
}

globalHandle := domain.GetDomain(sctx).BindHandle()
globalHandle.AddInvalidGlobalBinding(binding)
}

// setVarHintChecker checks whether the variable name in set_var hint is valid.
func setVarHintChecker(varName, hint string) (ok bool, warning error) {
sysVar := variable.GetSysVar(varName)
Expand Down