Skip to content

Commit

Permalink
planner: set cost model to ver1 for clusters upgrading from pre-6.1 v…
Browse files Browse the repository at this point in the history
…ersion (#39537)
  • Loading branch information
qw4990 authored Dec 1, 2022
1 parent 213187c commit c3565a1
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 0 deletions.
24 changes: 24 additions & 0 deletions session/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,9 @@ const (
version103 = 103
// version104 add `sql_digest` and `plan_digest` to `bind_info`
version104 = 104
// version105 insert "tidb_cost_model_version|1" to mysql.GLOBAL_VARIABLES if there is no tidb_cost_model_version.
// This will only happens when we upgrade a cluster before 6.0.
version105 = 105
)

// currentBootstrapVersion is defined as a variable, so we can modify its value for testing.
Expand Down Expand Up @@ -802,6 +805,7 @@ var (
upgradeToVer102,
upgradeToVer103,
upgradeToVer104,
upgradeToVer105,
}
)

Expand Down Expand Up @@ -2096,6 +2100,26 @@ func upgradeToVer104(s Session, ver int64) {
doReentrantDDL(s, "ALTER TABLE mysql.bind_info ADD COLUMN IF NOT EXISTS `plan_digest` varchar(64)")
}

// For users that upgrade TiDB from a pre-6.0 version, we want to disable tidb cost model2 by default to keep plans unchanged.
func upgradeToVer105(s Session, ver int64) {
if ver >= version105 {
return
}
ctx := kv.WithInternalSourceType(context.Background(), kv.InternalTxnBootstrap)
rs, err := s.ExecuteInternal(ctx, "SELECT VARIABLE_VALUE FROM %n.%n WHERE VARIABLE_NAME=%?;",
mysql.SystemDB, mysql.GlobalVariablesTable, variable.TiDBCostModelVersion)
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.TiDBCostModelVersion, "1")
}

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
143 changes: 143 additions & 0 deletions session/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1128,3 +1128,146 @@ func TestTiDBOptRangeMaxSizeWhenUpgrading(t *testing.T) {
require.Equal(t, 1, row.Len())
require.Equal(t, "0", row.GetString(0))
}

func TestTiDBCostModelInNewCluster(t *testing.T) {
store, err := mockstore.NewMockStore()
require.NoError(t, err)
// Indicates we are in a new cluster.
require.Equal(t, int64(notBootstrapped), getStoreBootstrapVersion(store))
dom, err := BootstrapSession(store)
require.NoError(t, err)
defer func() { require.NoError(t, store.Close()) }()
defer dom.Close()
se := createSessionAndSetID(t, store)

// In a new created cluster(above 6.5+), tidb_cost_model_version is 2 by default.
mustExec(t, se, "use test;")
r := mustExec(t, se, "select @@tidb_cost_model_version;")
require.NotNil(t, r)

ctx := context.Background()
chk := r.NewChunk(nil)
err = r.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, "2", row.GetString(0))
}

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

// Upgrade from 3.0.0 to 6.5+.
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.TiDBCostModelVersion))
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 TiDBCostModelVersion should not exist.
res := mustExec(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBCostModelVersion))
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 6.5+, TiDBCostModelVersion should be 1.
res = mustExec(t, seCurVer, "select @@tidb_cost_model_version")
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, "1", row.GetString(0))
}

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

// upgrade from 6.1 to 6.5+.
ver61 := 91
seV61 := createSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMeta(txn)
err = m.FinishBootstrap(int64(ver61))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
mustExec(t, seV61, fmt.Sprintf("update mysql.tidb set variable_value=%d where variable_name='tidb_server_version'", ver61))
mustExec(t, seV61, fmt.Sprintf("update mysql.GLOBAL_VARIABLES set variable_value='%s' where variable_name='%s'", "1", variable.TiDBCostModelVersion))
mustExec(t, seV61, "commit")
unsetStoreBootstrapped(store.UUID())
ver, err := getBootstrapVersion(seV61)
require.NoError(t, err)
require.Equal(t, int64(ver61), ver)

// We are now in 6.1, tidb_cost_model_version is 1.
res := mustExec(t, seV61, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", variable.TiDBCostModelVersion))
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, "1", row.GetString(1))

if i == 0 {
// For the first time, We set tidb_cost_model_version to 2.
// And after upgrade to 6.5, tidb_cost_model_version should be 2.
// For the second it should be 1.
mustExec(t, seV61, "set global tidb_cost_model_version = 2")
}
dom.Close()
// Upgrade to 6.5.
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 6.5.
res = mustExec(t, seCurVer, "select @@tidb_cost_model_version")
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, "2", row.GetString(0))
} else {
require.Equal(t, "1", row.GetString(0))
}
}()
}
}

0 comments on commit c3565a1

Please sign in to comment.