From a2d178c090e544d04c06433198a356a4844be1e0 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Thu, 1 Dec 2022 13:50:37 +0800 Subject: [PATCH 1/2] fixup --- session/bootstrap.go | 24 +++++++ session/bootstrap_test.go | 143 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/session/bootstrap.go b/session/bootstrap.go index 5dbffc42aa5f8..979be96e0288a 100644 --- a/session/bootstrap.go +++ b/session/bootstrap.go @@ -685,6 +685,9 @@ const ( version103 = 103 // version104 add `sql_digest` and `plan_digest` to `bind_info` version104 = 104 + // version104 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. @@ -798,6 +801,7 @@ var ( upgradeToVer102, upgradeToVer103, upgradeToVer104, + upgradeToVer105, } ) @@ -2092,6 +2096,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= %?`, diff --git a/session/bootstrap_test.go b/session/bootstrap_test.go index b17ced93e081c..91a6816893543 100644 --- a/session/bootstrap_test.go +++ b/session/bootstrap_test.go @@ -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 1 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 off. + 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)) + } + }() + } +} From d685480583db56d5ec00d4146d81379f114c5205 Mon Sep 17 00:00:00 2001 From: qw4990 Date: Thu, 1 Dec 2022 15:07:18 +0800 Subject: [PATCH 2/2] fiuxp --- session/bootstrap.go | 2 +- session/bootstrap_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/session/bootstrap.go b/session/bootstrap.go index 8781bd745791b..197b4b41cd934 100644 --- a/session/bootstrap.go +++ b/session/bootstrap.go @@ -689,7 +689,7 @@ const ( version103 = 103 // version104 add `sql_digest` and `plan_digest` to `bind_info` version104 = 104 - // version104 insert "tidb_cost_model_version|1" to mysql.GLOBAL_VARIABLES if there is no tidb_cost_model_version. + // 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 ) diff --git a/session/bootstrap_test.go b/session/bootstrap_test.go index 91a6816893543..73b1cfb7bd7c8 100644 --- a/session/bootstrap_test.go +++ b/session/bootstrap_test.go @@ -1140,7 +1140,7 @@ func TestTiDBCostModelInNewCluster(t *testing.T) { defer dom.Close() se := createSessionAndSetID(t, store) - // In a new created cluster(above 6.5+), tidb_cost_model_version is 1 by default. + // 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) @@ -1193,7 +1193,7 @@ func TestTiDBCostModelUpgradeFrom300To650(t *testing.T) { require.NoError(t, err) require.Equal(t, currentBootstrapVersion, ver) - // We are now in 6.5+, TiDBCostModelVersion should be off. + // 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)