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: support set binding status by sql digest #39517

Merged
merged 24 commits into from
Dec 21, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
188cd19
undo
fzzf678 Nov 24, 2022
a29174b
set bind status
fzzf678 Nov 27, 2022
499d4ff
Merge remote-tracking branch 'upstream/master' into binding_set
fzzf678 Nov 30, 2022
9d832ca
commit
fzzf678 Nov 30, 2022
795a136
Merge branch 'master' into binding_set
fzzf678 Nov 30, 2022
47a6057
Merge remote-tracking branch 'upstream/master' into binding_set
fzzf678 Dec 1, 2022
7911147
Update parser.go
fzzf678 Dec 1, 2022
3858448
Merge remote-tracking branch 'upstream/master' into binding_set
fzzf678 Dec 1, 2022
307dce2
Update parser.go
fzzf678 Dec 1, 2022
b26251d
commit
fzzf678 Dec 1, 2022
e858303
Revert "commit"
fzzf678 Dec 1, 2022
e8c5e77
Merge branch 'master' into binding_set
fzzf678 Dec 1, 2022
6b0ba15
Merge remote-tracking branch 'upstream/master' into binding_set
fzzf678 Dec 15, 2022
88a3470
ut
fzzf678 Dec 15, 2022
b668207
Merge branch 'master' into binding_set
fzzf678 Dec 15, 2022
b1aa4e7
refactor
fzzf678 Dec 15, 2022
dfa5e37
Merge branch 'binding_set' of https://github.com/fzzf678/tidb into bi…
fzzf678 Dec 15, 2022
a171777
Merge branch 'master' into binding_set
fzzf678 Dec 16, 2022
87fdcfd
Merge branch 'master' into binding_set
fzzf678 Dec 16, 2022
973d1e8
Merge branch 'master' into binding_set
fzzf678 Dec 19, 2022
d16e6b3
Merge branch 'master' into binding_set
fzzf678 Dec 20, 2022
16b65cf
Merge branch 'master' into binding_set
fzzf678 Dec 20, 2022
f94977d
Merge branch 'master' into binding_set
fzzf678 Dec 21, 2022
85fe88b
Merge branch 'master' into binding_set
ti-chi-bot Dec 21, 2022
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
9 changes: 9 additions & 0 deletions bindinfo/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,15 @@ func (h *BindHandle) SetBindRecordStatus(originalSQL string, binding *Binding, n
return
}

// SetBindRecordStatusByDigest set a BindRecord's status to the storage and bind cache.
func (h *BindHandle) SetBindRecordStatusByDigest(newStatus, sqlDigest string) (ok bool, err error) {
oldRecord, err := h.GetBindRecordBySQLDigest(sqlDigest)
if err != nil {
return false, err
}
return h.SetBindRecordStatus(oldRecord.OriginalSQL, nil, newStatus)
}

// GCBindRecord physically removes the deleted bind records in mysql.bind_info.
func (h *BindHandle) GCBindRecord() (err error) {
h.bindInfo.Lock()
Expand Down
11 changes: 11 additions & 0 deletions executor/bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ func (e *SQLBindExec) Next(ctx context.Context, req *chunk.Chunk) error {
return e.reloadBindings()
case plannercore.OpSetBindingStatus:
return e.setBindingStatus()
case plannercore.OpSetBindingStatusByDigest:
return e.setBindingStatusByDigest()
default:
return errors.Errorf("unsupported SQL bind operation: %v", e.sqlBindOp)
}
Expand Down Expand Up @@ -119,6 +121,15 @@ func (e *SQLBindExec) setBindingStatus() error {
return err
}

func (e *SQLBindExec) setBindingStatusByDigest() error {
ok, err := domain.GetDomain(e.ctx).BindHandle().SetBindRecordStatusByDigest(e.newStatus, e.sqlDigest)
if err == nil && !ok {
warningMess := errors.New("There are no bindings can be set the status. Please check the SQL text")
e.ctx.GetSessionVars().StmtCtx.AppendWarning(warningMess)
}
return err
}

func (e *SQLBindExec) createSQLBind() error {
// For audit log, SQLBindExec execute "explain" statement internally, save and recover stmtctx
// is necessary to avoid 'create binding' been recorded as 'explain'.
Expand Down
31 changes: 31 additions & 0 deletions infoschema/cluster_tables_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1028,3 +1028,34 @@ func TestBindingFromHistoryWithTiFlashBindable(t *testing.T) {
planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.statements_summary where query_sample_text = '%s'", sql)).Rows()
tk.MustGetErrMsg(fmt.Sprintf("create binding from history using plan digest '%s'", planDigest[0][0]), "can't create binding for query with tiflash engine")
}

func TestSetBindingStatusBySQLDigest(t *testing.T) {
s := new(clusterTablesSuite)
s.store, s.dom = testkit.CreateMockStoreAndDomain(t)
s.rpcserver, s.listenAddr = s.setUpRPCService(t, "127.0.0.1:0", nil)
s.httpServer, s.mockAddr = s.setUpMockPDHTTPServer()
s.startTime = time.Now()
defer s.httpServer.Close()
defer s.rpcserver.Stop()
tk := s.newTestKitWithRoot(t)
require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil))
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(id int, a int, key(a))")
sql := "select /*+ ignore_index(t, a) */ * from t where t.a = 1"
tk.MustExec(sql)
planDigest := tk.MustQuery(fmt.Sprintf("select plan_digest from information_schema.cluster_statements_summary where query_sample_text = '%s'", sql)).Rows()
tk.MustExec(fmt.Sprintf("create global binding from history using plan digest '%s'", planDigest[0][0]))
sql = "select * from t where t.a = 1"
tk.MustExec(sql)
tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1"))

sqlDigest := tk.MustQuery("show global bindings").Rows()
tk.MustExec(fmt.Sprintf("set binding disabled for sql digest '%s'", sqlDigest[0][9]))
tk.MustExec(sql)
tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("0"))
tk.MustExec(fmt.Sprintf("set binding enabled for sql digest '%s'", sqlDigest[0][9]))
tk.MustExec(sql)
tk.MustQuery("select @@last_plan_from_binding").Check(testkit.Rows("1"))
tk.MustGetErrMsg("set binding enabled for sql digest '2'", "can't find any binding for '2'")
}
2 changes: 2 additions & 0 deletions planner/core/common_plans.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ const (
OpSetBindingStatus
// OpSQLBindDropByDigest is used to drop SQL binds by digest
OpSQLBindDropByDigest
// OpSetBindingStatusByDigest represents the operation to set SQL binding status by sql digest.
OpSetBindingStatusByDigest
)

// SQLBindPlan represents a plan for SQL bind.
Expand Down
18 changes: 14 additions & 4 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1003,10 +1003,20 @@ func (b *PlanBuilder) buildDropBindPlan(v *ast.DropBindingStmt) (Plan, error) {
}

func (b *PlanBuilder) buildSetBindingStatusPlan(v *ast.SetBindingStmt) (Plan, error) {
p := &SQLBindPlan{
SQLBindOp: OpSetBindingStatus,
NormdOrigSQL: parser.Normalize(utilparser.RestoreWithDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, v.OriginNode.Text())),
Db: utilparser.GetDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB),
var p *SQLBindPlan
if v.OriginNode != nil {
p = &SQLBindPlan{
SQLBindOp: OpSetBindingStatus,
NormdOrigSQL: parser.Normalize(utilparser.RestoreWithDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB, v.OriginNode.Text())),
Db: utilparser.GetDefaultDB(v.OriginNode, b.ctx.GetSessionVars().CurrentDB),
}
} else if v.SQLDigest != "" {
p = &SQLBindPlan{
SQLBindOp: OpSetBindingStatusByDigest,
SQLDigest: v.SQLDigest,
}
} else {
return nil, errors.New("sql digest is empty")
}
switch v.BindingStatusType {
case ast.BindingStatusTypeEnabled:
Expand Down