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

bindinfo: rename Using status to Enabled status #32801

Merged
merged 16 commits into from
Mar 7, 2022
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
21 changes: 17 additions & 4 deletions bindinfo/bind_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ import (
)

const (
// Enabled is the bind info's in enabled status.
// It is the same as the previous 'Using' status.
// Only use 'Enabled' status in the future, not the 'Using' status.
// The 'Using' status is preserved for compatibility.
Enabled = "enabled"
// Disabled is the bind info's in disabled status.
Disabled = "disabled"
// Using is the bind info's in use status.
// The 'Using' status is preserved for compatibility.
Using = "using"
// deleted is the bind info's deleted status.
deleted = "deleted"
Expand All @@ -53,7 +61,7 @@ type Binding struct {
BindSQL string
// Status represents the status of the binding. It can only be one of the following values:
// 1. deleted: BindRecord is deleted, can not be used anymore.
// 2. using: Binding is in the normal active mode.
// 2. enabled, using: Binding is in the normal active mode.
Status string
CreateTime types.Time
UpdateTime types.Time
Expand All @@ -74,6 +82,11 @@ func (b *Binding) isSame(rb *Binding) bool {
return b.BindSQL == rb.BindSQL
}

// IsBindingEnabled returns whether the binding is enabled.
func (b *Binding) IsBindingEnabled() bool {
return b.Status == Enabled || b.Status == Using
}

// SinceUpdateTime returns the duration since last update time. Export for test.
func (b *Binding) SinceUpdateTime() (time.Duration, error) {
updateTime, err := b.UpdateTime.GoTime(time.Local)
Expand All @@ -94,7 +107,7 @@ type BindRecord struct {
// HasUsingBinding checks if there are any using bindings in bind record.
func (br *BindRecord) HasUsingBinding() bool {
for _, binding := range br.Bindings {
if binding.Status == Using {
if binding.IsBindingEnabled() {
return true
}
}
Expand All @@ -105,7 +118,7 @@ func (br *BindRecord) HasUsingBinding() bool {
// There is at most one binding that can be used now
func (br *BindRecord) FindUsingBinding() *Binding {
for _, binding := range br.Bindings {
if binding.Status == Using {
if binding.IsBindingEnabled() {
return &binding
}
}
Expand Down Expand Up @@ -242,7 +255,7 @@ func (br *BindRecord) size() float64 {
}

var statusIndex = map[string]int{
Using: 0,
Enabled: 0,
deleted: 1,
Invalid: 2,
}
Expand Down
26 changes: 13 additions & 13 deletions bindinfo/bind_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func TestBindingSymbolList(t *testing.T) {
bind := bindData.Bindings[0]
require.Equal(t, "SELECT `a`,`b` FROM `test`.`t` USE INDEX (`ib`) WHERE `a` = 1 LIMIT 0,1", bind.BindSQL)
require.Equal(t, "test", bindData.Db)
require.Equal(t, "using", bind.Status)
require.Equal(t, bindinfo.Enabled, bind.Status)
require.NotNil(t, bind.Charset)
require.NotNil(t, bind.Collation)
require.NotNil(t, bind.CreateTime)
Expand Down Expand Up @@ -498,7 +498,7 @@ func TestBestPlanInBaselines(t *testing.T) {
bind := bindData.Bindings[0]
require.Equal(t, "SELECT /*+ use_index(@`sel_1` `test`.`t` `ia`)*/ `a`,`b` FROM `test`.`t` WHERE `a` = 1 LIMIT 0,1", bind.BindSQL)
require.Equal(t, "test", bindData.Db)
require.Equal(t, "using", bind.Status)
require.Equal(t, bindinfo.Enabled, bind.Status)

tk.MustQuery("select a, b from t where a = 3 limit 1, 10")
require.Equal(t, "t:ia", tk.Session().GetSessionVars().StmtCtx.IndexNames[0])
Expand Down Expand Up @@ -532,7 +532,7 @@ func TestErrorBind(t *testing.T) {
bind := bindData.Bindings[0]
require.Equal(t, "SELECT * FROM `test`.`t` USE INDEX (`index_t`) WHERE `i` > 100", bind.BindSQL)
require.Equal(t, "test", bindData.Db)
require.Equal(t, "using", bind.Status)
require.Equal(t, bindinfo.Enabled, bind.Status)
require.NotNil(t, bind.Charset)
require.NotNil(t, bind.Collation)
require.NotNil(t, bind.CreateTime)
Expand Down Expand Up @@ -651,7 +651,7 @@ func TestAddEvolveTasks(t *testing.T) {
require.Len(t, rows, 2)
require.Equal(t, "SELECT /*+ use_index(@`sel_1` `test`.`t` )*/ * FROM `test`.`t` WHERE `a` >= 4 AND `b` >= 1 AND `c` = 0", rows[0][1])
status := rows[0][3].(string)
require.True(t, status == "using" || status == "rejected")
require.True(t, status == bindinfo.Enabled || status == bindinfo.Rejected)
}

func TestRuntimeHintsInEvolveTasks(t *testing.T) {
Expand Down Expand Up @@ -910,7 +910,7 @@ func TestNotEvolvePlanForReadStorageHint(t *testing.T) {
// None evolve task, because of the origin binding is a read_from_storage binding.
require.Len(t, rows, 1)
require.Equal(t, "SELECT /*+ read_from_storage(tiflash[`t`])*/ * FROM `test`.`t` WHERE `a` >= 1 AND `b` >= 1", rows[0][1])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])
}

func TestBindingWithIsolationRead(t *testing.T) {
Expand Down Expand Up @@ -1055,23 +1055,23 @@ func TestReCreateBind(t *testing.T) {

tk.MustExec("create global binding for select * from t using select * from t")
tk.MustQuery("select original_sql, status from mysql.bind_info where source != 'builtin';").Check(testkit.Rows(
"select * from `test` . `t` using",
"select * from `test` . `t` enabled",
))
rows := tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t`", rows[0][0])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])

tk.MustExec("create global binding for select * from t using select * from t")
rows = tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t`", rows[0][0])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])

rows = tk.MustQuery("select original_sql, status from mysql.bind_info where source != 'builtin';").Rows()
require.Len(t, rows, 2)
require.Equal(t, "deleted", rows[0][1])
require.Equal(t, "using", rows[1][1])
require.Equal(t, bindinfo.Enabled, rows[1][1])
}

func TestExplainShowBindSQL(t *testing.T) {
Expand Down Expand Up @@ -1218,9 +1218,9 @@ func TestGCBindRecord(t *testing.T) {
rows := tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t` where `a` = ?", rows[0][0])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])
tk.MustQuery("select status from mysql.bind_info where original_sql = 'select * from `test` . `t` where `a` = ?'").Check(testkit.Rows(
"using",
bindinfo.Enabled,
))

h := dom.BindHandle()
Expand All @@ -1229,9 +1229,9 @@ func TestGCBindRecord(t *testing.T) {
rows = tk.MustQuery("show global bindings").Rows()
require.Len(t, rows, 1)
require.Equal(t, "select * from `test` . `t` where `a` = ?", rows[0][0])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])
tk.MustQuery("select status from mysql.bind_info where original_sql = 'select * from `test` . `t` where `a` = ?'").Check(testkit.Rows(
"using",
bindinfo.Enabled,
))

tk.MustExec("drop global binding for select * from t where a = 1")
Expand Down
8 changes: 4 additions & 4 deletions bindinfo/capture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func TestCaptureBaselinesDefaultDB(t *testing.T) {
require.Len(t, rows, 1)
// Default DB should be "" when all columns have explicit database name.
require.Equal(t, "", rows[0][2])
require.Equal(t, "using", rows[0][3])
require.Equal(t, bindinfo.Enabled, rows[0][3])
tk.MustExec("use spm")
tk.MustExec("select * from spm.t where a > 10")
// Should use TableScan because of the "ignore index" binding.
Expand Down Expand Up @@ -345,7 +345,7 @@ func TestConcurrentCapture(t *testing.T) {

// Simulate an existing binding generated by concurrent CREATE BINDING, which has not been synchronized to current tidb-server yet.
// Actually, it is more common to be generated by concurrent baseline capture, I use Manual just for simpler test verification.
tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t`', 'select * from `test` . `t`', '', 'using', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" +
tk.MustExec("insert into mysql.bind_info values('select * from `test` . `t`', 'select * from `test` . `t`', '', 'enabled', '2000-01-01 09:00:00', '2000-01-01 09:00:00', '', '','" +
bindinfo.Manual + "')")
tk.MustQuery("select original_sql, source from mysql.bind_info where source != 'builtin'").Check(testkit.Rows(
"select * from `test` . `t` manual",
Expand All @@ -360,7 +360,7 @@ func TestConcurrentCapture(t *testing.T) {
tk.MustExec("admin capture bindings")
tk.MustQuery("select original_sql, source, status from mysql.bind_info where source != 'builtin'").Check(testkit.Rows(
"select * from `test` . `t` manual deleted",
"select * from `test` . `t` capture using",
"select * from `test` . `t` capture enabled",
))
}

Expand Down Expand Up @@ -461,7 +461,7 @@ func TestIssue20417(t *testing.T) {
require.Equal(t, "select * from `test` . `t` where `c` = ?", rows[0][0])
require.Equal(t, "SELECT /*+ use_index(@`sel_1` `test`.`t` `idxc`)*/ * FROM `test`.`t` WHERE `c` = 3924541", rows[0][1])
status := rows[0][3].(string)
require.True(t, status == "using" || status == "rejected")
require.True(t, status == bindinfo.Enabled || status == bindinfo.Rejected)
tk.MustExec("set @@tidb_evolve_plan_baselines=0")
}

Expand Down
11 changes: 8 additions & 3 deletions bindinfo/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,14 @@ func (h *BindHandle) SetBindCacheCapacity(capacity int64) {

// newBindRecord builds BindRecord from a tuple in storage.
func (h *BindHandle) newBindRecord(row chunk.Row) (string, *BindRecord, error) {
status := row.GetString(3)
// For compatibility, the 'Using' status binding will be converted to the 'Enabled' status binding.
if status == Using {
status = Enabled
}
hint := Binding{
BindSQL: row.GetString(1),
Status: row.GetString(3),
Status: status,
CreateTime: row.GetTime(4),
UpdateTime: row.GetTime(5),
Charset: row.GetString(6),
Expand Down Expand Up @@ -749,7 +754,7 @@ func (h *BindHandle) CaptureBaselines() {
charset, collation := h.sctx.GetSessionVars().GetCharsetInfo()
binding := Binding{
BindSQL: bindSQL,
Status: Using,
Status: Enabled,
Charset: charset,
Collation: collation,
Source: Capture,
Expand Down Expand Up @@ -1061,7 +1066,7 @@ func (h *BindHandle) HandleEvolvePlanTask(sctx sessionctx.Context, adminEvolve b
zap.String("digestText", digestText),
)
} else {
binding.Status = Using
binding.Status = Enabled
}
// We don't need to pass the `sctx` because the BindSQL has been validated already.
return h.AddBindRecord(nil, &BindRecord{OriginalSQL: originalSQL, Db: db, Bindings: []Binding{binding}})
Expand Down
Loading