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

sessionctx: enable IndexMerge by default #30650

Merged
merged 15 commits into from
Dec 27, 2021
Merged
Show file tree
Hide file tree
Changes from 5 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
22 changes: 13 additions & 9 deletions cmd/explaintest/r/explain_indexmerge.result
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ create index td on t (d);
load stats 's/explain_indexmerge_stats_t.json';
explain format = 'brief' select * from t where a < 50 or b < 50;
id estRows task access object operator info
TableReader 98.00 root data:Selection
└─Selection 98.00 cop[tikv] or(lt(test.t.a, 50), lt(test.t.b, 50))
└─TableFullScan 5000000.00 cop[tikv] table:t keep order:false
IndexMerge 98.00 root
├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false
├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false
└─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false
explain format = 'brief' select * from t where (a < 50 or b < 50) and f > 100;
id estRows task access object operator info
TableReader 98.00 root data:Selection
└─Selection 98.00 cop[tikv] gt(test.t.f, 100), or(lt(test.t.a, 50), lt(test.t.b, 50))
└─TableFullScan 5000000.00 cop[tikv] table:t keep order:false
IndexMerge 98.00 root
├─TableRangeScan(Build) 49.00 cop[tikv] table:t range:[-inf,50), keep order:false
├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false
└─Selection(Probe) 98.00 cop[tikv] gt(test.t.f, 100)
└─TableRowIDScan 98.00 cop[tikv] table:t keep order:false
explain format = 'brief' select * from t where b < 50 or c < 50;
id estRows task access object operator info
TableReader 98.00 root data:Selection
└─Selection 98.00 cop[tikv] or(lt(test.t.b, 50), lt(test.t.c, 50))
└─TableFullScan 5000000.00 cop[tikv] table:t keep order:false
IndexMerge 98.00 root
├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tb(b) range:[-inf,50), keep order:false
├─IndexRangeScan(Build) 49.00 cop[tikv] table:t, index:tc(c) range:[-inf,50), keep order:false
└─TableRowIDScan(Probe) 98.00 cop[tikv] table:t keep order:false
set session tidb_enable_index_merge = on;
explain format = 'brief' select * from t where a < 50 or b < 50;
id estRows task access object operator info
Expand Down
4 changes: 4 additions & 0 deletions planner/core/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2203,6 +2203,10 @@ func (s *testIntegrationSuite) TestOptimizeHintOnPartitionTable(c *C) {
partition p1 values less than(11),
partition p2 values less than(16));`)
tk.MustExec(`insert into t values (1,1,"1"), (2,2,"2"), (8,8,"8"), (11,11,"11"), (15,15,"15")`)
tk.MustExec("set @@tidb_enable_index_merge = off")
defer func() {
tk.MustExec("set @@tidb_enable_index_merge = on")
}()

// Create virtual tiflash replica info.
dom := domain.GetDomain(tk.Se)
Expand Down
12 changes: 6 additions & 6 deletions planner/core/testdata/plan_suite_out.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@
},
{
"SQL": "select /*+ USE_INDEX_MERGE(t1, c_d_e, f_g) */ * from t where c < 1 or f > 2",
"Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))",
"Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f)[(2,+inf]]], TablePlan->Table(t))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
"Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f`)"
},
{
"SQL": "select /*+ NO_INDEX_MERGE(), USE_INDEX_MERGE(t, primary, f_g, c_d_e) */ * from t where a < 1 or f > 2",
Expand All @@ -304,15 +304,15 @@
},
{
"SQL": "select /*+ USE_INDEX_MERGE(db2.t) */ * from t where c < 1 or f > 2",
"Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))",
"Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f)[(2,+inf]]], TablePlan->Table(t))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
"Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f`)"
},
{
"SQL": "select /*+ USE_INDEX_MERGE(db2.t, c_d_e, f_g) */ * from t where c < 1 or f > 2",
"Best": "TableReader(Table(t)->Sel([or(lt(test.t.c, 1), gt(test.t.f, 2))]))",
"Best": "IndexMergeReader(PartialPlans->[Index(t.c_d_e)[[-inf,1)], Index(t.f)[(2,+inf]]], TablePlan->Table(t))",
"HasWarn": true,
"Hints": "use_index(@`sel_1` `test`.`t` )"
"Hints": "use_index_merge(@`sel_1` `t` `c_d_e`, `f`)"
}
]
},
Expand Down
27 changes: 26 additions & 1 deletion session/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,11 +538,14 @@ const (
version78 = 78
// version79 adds the mysql.table_cache_meta table
version79 = 79
// version80 insert "tidb_enable_index_merge|off" to mysql.GLOBAL_VARIABLES if there is no tidb_enable_index_merge.
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
// This will only happens when we upgrade a cluster before 4.0.0 to 4.0.0+.
version80 = 80
)

// currentBootstrapVersion is defined as a variable, so we can modify its value for testing.
// please make sure this is the largest version
var currentBootstrapVersion int64 = version79
var currentBootstrapVersion int64 = version80

var (
bootstrapVersion = []func(Session, int64){
Expand Down Expand Up @@ -625,6 +628,7 @@ var (
upgradeToVer77,
upgradeToVer78,
upgradeToVer79,
upgradeToVer80,
}
)

Expand Down Expand Up @@ -1630,6 +1634,27 @@ func upgradeToVer79(s Session, ver int64) {
doReentrantDDL(s, CreateTableCacheMetaTable)
}

func upgradeToVer80(s Session, ver int64) {
if ver >= version80 {
return
}
// Check if tidb_enable_index_merge exists in mysql.GLOBAL_VARIABLES.
// If not, insert "tidb_enable_index_merge | off".
ctx := context.Background()
rs, err := s.ExecuteInternal(ctx, "SELECT VARIABLE_VALUE FROM %n.%n WHERE VARIABLE_NAME=%?;",
mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBEnableIndexMerge)
terror.MustNil(err)
req := rs.NewChunk(nil)
err = rs.Next(ctx, req)
terror.MustNil(err)
if req.NumRows() != 0 {
return
}

mustExecute(s, "INSERT HIGH_PRIORITY IGNORE INTO %n.%n VALUES (%?, %?);",
mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBEnableIndexMerge, variable.Off)
guo-shaoge marked this conversation as resolved.
Show resolved Hide resolved
}

func writeOOMAction(s Session) {
comment := "oom-action is `log` by default in v3.0.x, `cancel` by default in v4.0.11+"
mustExecute(s, `INSERT HIGH_PRIORITY INTO %n.%n VALUES (%?, %?, %?) ON DUPLICATE KEY UPDATE VARIABLE_VALUE= %?`,
Expand Down
115 changes: 115 additions & 0 deletions session/bootstrap_serial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -879,3 +879,118 @@ func TestReferencesPrivilegeOnColumn(t *testing.T) {
mustExec(t, se, "create table t1 (a int)")
mustExec(t, se, "GRANT select (a), update (a),insert(a), references(a) on t1 to issue28531")
}

func TestIndexMergeUpgradeFrom300To500(t *testing.T) {
ctx := context.Background()
store, _ := createStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()

// Upgrade from 3.0.0 to 5.4+.
ver300 := 33
seV3 := createSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMeta(txn)
err = m.FinishBootstrap(int64(ver300))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
mustExec(t, seV3, fmt.Sprintf("update mysql.tidb set variable_value=%d where variable_name='tidb_server_version'", ver300))
mustExec(t, seV3, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableIndexMerge))
mustExec(t, seV3, "commit")
unsetStoreBootstrapped(store.UUID())
ver, err := getBootstrapVersion(seV3)
require.NoError(t, err)
require.Equal(t, int64(ver300), ver)

// We are now in 3.0.0, check tidb_enable_index_merge shoudle not exist.
res := mustExec(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableIndexMerge))
chk := res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 0, chk.NumRows())

domCurVer, err := BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := createSessionAndSetID(t, store)
ver, err = getBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, currentBootstrapVersion, ver)

// We are now in 5.x, tidb_enable_index_merge should be off.
res = mustExec(t, seCurVer, "select @@tidb_enable_index_merge")
chk = res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 1, chk.NumRows())
row := chk.GetRow(0)
require.Equal(t, 1, row.Len())
require.Equal(t, int64(0), row.GetInt64(0))
}

func TestIndexMergeUpgradeFrom400To500(t *testing.T) {
for i := 0; i < 2; i++ {
ctx := context.Background()
store, _ := createStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()

// upgrade from 4.0.0 to 5.4+.
ver400 := 46
seV4 := createSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMeta(txn)
err = m.FinishBootstrap(int64(ver400))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
mustExec(t, seV4, fmt.Sprintf("update mysql.tidb set variable_value=%d where variable_name='tidb_server_version'", ver400))
mustExec(t, seV4, fmt.Sprintf("update mysql.GLOBAL_VARIABLES set variable_value='%s' where variable_name='%s'", variable.Off, variable.TiDBEnableIndexMerge))
mustExec(t, seV4, "commit")
unsetStoreBootstrapped(store.UUID())
ver, err := getBootstrapVersion(seV4)
require.NoError(t, err)
require.Equal(t, int64(ver400), ver)

// We are now in 4.0.0, tidb_enable_index_merge is off.
res := mustExec(t, seV4, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBEnableIndexMerge))
chk := res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 1, chk.NumRows())
row := chk.GetRow(0)
require.Equal(t, 2, row.Len())
require.Equal(t, variable.Off, row.GetString(1))

if i == 0 {
// For the first time, We set tidb_enable_index_merge as on.
// And after upgrade to 5.x, tidb_enable_index_merge should remains to be on.
// For the second it should be off.
mustExec(t, seV4, "set global tidb_enable_index_merge = on")
}

// Upgrade to 5.x.
domCurVer, err := BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := createSessionAndSetID(t, store)
ver, err = getBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, currentBootstrapVersion, ver)

// We are now in 5.x, tidb_enable_index_merge should be on because we enable it in 4.0.0.
res = mustExec(t, seCurVer, "select @@tidb_enable_index_merge")
chk = res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 1, chk.NumRows())
row = chk.GetRow(0)
require.Equal(t, 1, row.Len())
if i == 0 {
require.Equal(t, int64(1), row.GetInt64(0))
} else {
require.Equal(t, int64(0), row.GetInt64(0))
}
}
}
2 changes: 1 addition & 1 deletion sessionctx/variable/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ func NewSessionVars() *SessionVars {
SlowQueryFile: config.GetGlobalConfig().Log.SlowQueryFile,
WaitSplitRegionFinish: DefTiDBWaitSplitRegionFinish,
WaitSplitRegionTimeout: DefWaitSplitRegionTimeout,
enableIndexMerge: false,
enableIndexMerge: DefTiDBEnableIndexMerge,
NoopFuncsMode: TiDBOptOnOffWarn(DefTiDBEnableNoopFuncs),
replicaRead: kv.ReplicaReadLeader,
AllowRemoveAutoInc: DefTiDBAllowRemoveAutoInc,
Expand Down
2 changes: 1 addition & 1 deletion sessionctx/variable/sysvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ var defaultSysVars = []*SysVar{
s.SetEnableCascadesPlanner(TiDBOptOn(val))
return nil
}},
{Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableIndexMerge, Value: Off, Type: TypeBool, SetSession: func(s *SessionVars, val string) error {
{Scope: ScopeGlobal | ScopeSession, Name: TiDBEnableIndexMerge, Value: BoolToOnOff(DefTiDBEnableIndexMerge), Type: TypeBool, SetSession: func(s *SessionVars, val string) error {
s.SetEnableIndexMerge(TiDBOptOn(val))
return nil
}},
Expand Down
9 changes: 9 additions & 0 deletions sessionctx/variable/sysvar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,3 +825,12 @@ func TestDefaultCharsetAndCollation(t *testing.T) {
require.NoError(t, err)
require.Equal(t, val, mysql.DefaultCollationName)
}

func TestIndexMergeSwitcher(t *testing.T) {
vars := NewSessionVars()
vars.GlobalVarsAccessor = NewMockGlobalAccessor4Tests()
val, err := GetSessionOrGlobalSystemVar(vars, TiDBEnableIndexMerge)
require.NoError(t, err)
require.Equal(t, DefTiDBEnableIndexMerge, true)
require.Equal(t, BoolToOnOff(DefTiDBEnableIndexMerge), val)
}
1 change: 1 addition & 0 deletions sessionctx/variable/tidb_vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,7 @@ const (
DefTiDBRegardNULLAsPoint = true
DefEnablePlacementCheck = true
DefTimestamp = "0"
DefTiDBEnableIndexMerge = true
)

// Process global variables.
Expand Down