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, bindinfo: support show bindings order by update_time #26139

Merged
merged 23 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6d9c31b
show global bindings order by update_time
Reminiscent Jul 12, 2021
cc8202b
Merge branch 'master' of https://github.com/pingcap/tidb into issue#1…
Reminiscent Jul 12, 2021
dface24
fix ut
Reminiscent Jul 12, 2021
1f92ea8
Merge branch 'master' of https://github.com/pingcap/tidb into issue#1…
Reminiscent Jul 12, 2021
f181d84
address comments
Reminiscent Jul 14, 2021
e25a6d6
Merge branch 'master' of https://github.com/pingcap/tidb into issue#1…
Reminiscent Jul 14, 2021
d98baa7
Merge branch 'master' into issue#15702
eurekaka Aug 2, 2021
02ba738
add more tests
Reminiscent Aug 3, 2021
d19d15d
Merge branch 'master' of https://github.com/pingcap/tidb into issue#1…
Reminiscent Aug 3, 2021
54cce49
Merge branch 'issue#15702' of https://github.com/Reminiscent/tidb int…
Reminiscent Aug 3, 2021
0ef4f7a
use the stable sort
Reminiscent Aug 4, 2021
897ffe7
Merge branch 'master' of https://github.com/pingcap/tidb into issue#1…
Reminiscent Aug 4, 2021
89b3956
Merge branch 'master' into issue#15702
ti-chi-bot Aug 4, 2021
b4c6af3
Merge branch 'master' into issue#15702
ti-chi-bot Aug 4, 2021
3160baf
Merge branch 'master' into issue#15702
ti-chi-bot Aug 4, 2021
74e543e
Merge branch 'master' into issue#15702
ti-chi-bot Aug 4, 2021
67cb27b
Merge branch 'master' into issue#15702
ti-chi-bot Aug 4, 2021
003c19f
Merge branch 'master' into issue#15702
ti-chi-bot Aug 4, 2021
49a0cce
Merge branch 'master' of https://github.com/pingcap/tidb into issue#1…
Reminiscent Aug 4, 2021
7c87488
Merge branch 'issue#15702' of https://github.com/Reminiscent/tidb int…
Reminiscent Aug 4, 2021
7b25c17
fix ut
Reminiscent Aug 4, 2021
aff20d9
Merge branch 'master' into issue#15702
ti-chi-bot Aug 4, 2021
075ae0e
Merge branch 'master' into issue#15702
ti-chi-bot Aug 4, 2021
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
64 changes: 49 additions & 15 deletions bindinfo/bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,40 @@ func (s *testSuite) TestBaselineDBLowerCase(c *C) {
))
}

func (s *testSuite) TestShowGlobalBindings(c *C) {
tk := testkit.NewTestKit(c, s.store)
s.cleanBindingEnv(tk)
stmtsummary.StmtSummaryByDigestMap.Clear()
tk.MustExec("drop database if exists SPM")
tk.MustExec("create database SPM")
tk.MustExec("use SPM")
tk.MustExec("create table t(a int, key(a))")
tk.MustExec("create table t0(a int, key(a))")
c.Assert(tk.Se.Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil), IsTrue)
rows := tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 0)
// Simulate existing bindings in the mysql.bind_info.
tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t`', 'select * from `spm` . `t` USE INDEX (`a`)', 'SPM', 'using', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" +
bindinfo.Manual + "')")
tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t0`', 'select * from `spm` . `t0` USE INDEX (`a`)', 'SPM', 'using', '2000-01-02 09:00:00', '2000-01-02 09:00:00', '', '','" +
bindinfo.Manual + "')")
tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t`', 'select /*+ use_index(`t` `a`)*/ * from `spm` . `t`', 'SPM', 'using', '2000-01-03 09:00:00', '2000-01-03 09:00:00', '', '','" +
bindinfo.Manual + "')")
tk.MustExec("insert into mysql.bind_info values('select * from `spm` . `t0`', 'select /*+ use_index(`t0` `a`)*/ * from `spm` . `t0`', 'SPM', 'using', '2000-01-04 09:00:00', '2000-01-04 09:00:00', '', '','" +
bindinfo.Manual + "')")
tk.MustExec("admin reload bindings")
rows = tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 4)
c.Assert(rows[0][0], Equals, "select * from `spm` . `t0`")
c.Assert(rows[0][5], Equals, "2000-01-04 09:00:00.000")
c.Assert(rows[1][0], Equals, "select * from `spm` . `t0`")
c.Assert(rows[1][5], Equals, "2000-01-02 09:00:00.000")
c.Assert(rows[2][0], Equals, "select * from `spm` . `t`")
c.Assert(rows[2][5], Equals, "2000-01-03 09:00:00.000")
c.Assert(rows[3][0], Equals, "select * from `spm` . `t`")
c.Assert(rows[3][5], Equals, "2000-01-01 09:00:00.000")
}

func (s *testSuite) TestCaptureBaselinesDefaultDB(c *C) {
tk := testkit.NewTestKit(c, s.store)
s.cleanBindingEnv(tk)
Expand Down Expand Up @@ -1241,13 +1275,13 @@ func (s *testSuite) TestAddEvolveTasks(c *C) {
tk.MustExec("admin flush bindings")
rows := tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 2)
c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0")
c.Assert(rows[1][3], Equals, "pending verify")
c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0")
c.Assert(rows[0][3], Equals, "pending verify")
tk.MustExec("admin evolve bindings")
rows = tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 2)
c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0")
status := rows[1][3].(string)
c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0")
status := rows[0][3].(string)
c.Assert(status == "using" || status == "rejected", IsTrue)
}

Expand All @@ -1261,19 +1295,19 @@ func (s *testSuite) TestRuntimeHintsInEvolveTasks(c *C) {

// these runtime hints which don't be contained by the original binding should be ignored
tk.MustExec("create global binding for select * from t where a >= 1 and b >= 1 and c = 0 using select * from t use index(idx_a) where a >= 1 and b >= 1 and c = 0")
tk.MustQuery("select /*+ MAX_EXECUTION_TIME(5000) */* from t where a >= 4 and b >= 1 and c = 0")
tk.MustQuery("select /*+ MAX_EXECUTION_TIME(5000) */ * from t where a >= 4 and b >= 1 and c = 0")
tk.MustExec("admin flush bindings")
rows := tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 2)
c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idx_c`)*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0") // MAX_EXECUTION_TIME is ignored
c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idx_c`)*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0") // MAX_EXECUTION_TIME is ignored

s.cleanBindingEnv(tk)
tk.MustExec("create global binding for select * from t where a >= 1 and b >= 1 and c = 0 using select /*+ MAX_EXECUTION_TIME(5000) */* from t use index(idx_a) where a >= 1 and b >= 1 and c = 0")
tk.MustQuery("select /*+ MAX_EXECUTION_TIME(5000) */* from t where a >= 4 and b >= 1 and c = 0")
tk.MustExec("admin flush bindings")
rows = tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 2)
c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idx_c`), max_execution_time(5000)*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0")
c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idx_c`), max_execution_time(5000)*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0")
}

func (s *testSuite) TestBindingCache(c *C) {
Expand Down Expand Up @@ -1721,8 +1755,8 @@ func (s *testSuite) TestReCreateBindAfterEvolvePlan(c *C) {
tk.MustExec("admin flush bindings")
rows := tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 2)
c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a` >= 0 AND `b` >= 0")
c.Assert(rows[1][3], Equals, "pending verify")
c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a` >= 0 AND `b` >= 0")
c.Assert(rows[0][3], Equals, "pending verify")

tk.MustExec("create global binding for select * from t where a >= 1 and b >= 1 using select * from t use index(idx_b) where a >= 1 and b >= 1")
rows = tk.MustQuery("show global bindings").Rows()
Expand Down Expand Up @@ -2027,15 +2061,15 @@ func (s *testSuite) TestIssue20417(c *C) {
tk.MustExec("admin flush bindings")
rows = tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 2)
c.Assert(rows[1][0], Equals, "select * from `test` . `t` where `c` = ?")
c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idxc`), use_index(`t` `idxc`)*/ * FROM `test`.`t` WHERE `c` = 3924541")
c.Assert(rows[1][3], Equals, "pending verify")
c.Assert(rows[0][0], Equals, "select * from `test` . `t` where `c` = ?")
c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idxc`), use_index(`t` `idxc`)*/ * FROM `test`.`t` WHERE `c` = 3924541")
c.Assert(rows[0][3], Equals, "pending verify")
tk.MustExec("admin evolve bindings")
rows = tk.MustQuery("show global bindings").Rows()
c.Assert(len(rows), Equals, 2)
c.Assert(rows[1][0], Equals, "select * from `test` . `t` where `c` = ?")
c.Assert(rows[1][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idxc`), use_index(`t` `idxc`)*/ * FROM `test`.`t` WHERE `c` = 3924541")
status := rows[1][3].(string)
c.Assert(rows[0][0], Equals, "select * from `test` . `t` where `c` = ?")
c.Assert(rows[0][1], Equals, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idxc`), use_index(`t` `idxc`)*/ * FROM `test`.`t` WHERE `c` = 3924541")
status := rows[0][3].(string)
c.Assert(status == "using" || status == "rejected", IsTrue)
tk.MustExec("set @@tidb_evolve_plan_baselines=0")
}
Expand Down
21 changes: 21 additions & 0 deletions executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,28 @@ func (e *ShowExec) fetchShowBind() error {
} else {
bindRecords = domain.GetDomain(e.ctx).BindHandle().GetAllBindRecord()
}
// Remove the invalid bindRecord.
ind := 0
for _, bindData := range bindRecords {
if len(bindData.Bindings) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

How could this happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When the session binding is deleted, len(bindData.Bindings) maybe 0.

bindRecords[ind] = bindData
ind++
}
}
bindRecords = bindRecords[:ind]
parser := parser.New()
for _, bindData := range bindRecords {
// For the same origin_sql, sort the bindings according to their update time.
sort.Slice(bindData.Bindings, func(i int, j int) bool {
cmpResult := bindData.Bindings[i].UpdateTime.Compare(bindData.Bindings[j].UpdateTime)
return cmpResult > 0
})
}
// For the different origin_sql, sort the bindRecords according to their max update time.
sort.Slice(bindRecords, func(i int, j int) bool {
Copy link
Member

Choose a reason for hiding this comment

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

use stable sort instead?

cmpResult := bindRecords[i].Bindings[0].UpdateTime.Compare(bindRecords[j].Bindings[0].UpdateTime)
return cmpResult > 0
})
for _, bindData := range bindRecords {
for _, hint := range bindData.Bindings {
stmt, err := parser.ParseOneStmt(hint.BindSQL, hint.Charset, hint.Collation)
Expand Down