Files
tidb/pkg/session/test/bootstraptest/boot_test.go

878 lines
32 KiB
Go

// Copyright 2026 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package bootstraptest
import (
"context"
"fmt"
"testing"
"time"
"github.com/pingcap/tidb/pkg/config/kerneltype"
"github.com/pingcap/tidb/pkg/meta"
"github.com/pingcap/tidb/pkg/session"
"github.com/pingcap/tidb/pkg/sessionctx/vardef"
"github.com/pingcap/tidb/pkg/statistics"
"github.com/pingcap/tidb/pkg/testkit/testfailpoint"
"github.com/pingcap/tidb/pkg/types"
"github.com/stretchr/testify/require"
)
func match(t *testing.T, row []types.Datum, expected ...any) {
require.Len(t, row, len(expected))
for i := range row {
if _, ok := expected[i].(time.Time); ok {
// Since password_last_changed is set to default current_timestamp, we pass this check.
continue
}
got := fmt.Sprintf("%v", row[i].GetValue())
need := fmt.Sprintf("%v", expected[i])
require.Equal(t, need, got, i)
}
}
func TestWriteDDLTableVersionToMySQLTiDB(t *testing.T) {
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
ddlTableVer, err := m.GetDDLTableVersion()
require.NoError(t, err)
// Verify that 'ddl_table_version' has been set to the correct value
se := session.CreateSessionAndSetID(t, store)
r := session.MustExecToRecodeSet(t, se, fmt.Sprintf(`SELECT VARIABLE_VALUE from mysql.TiDB where VARIABLE_NAME='%s'`, session.TiDBDDLTableVersionForTest))
req := r.NewChunk(nil)
err = r.Next(ctx, req)
require.NoError(t, err)
require.Equal(t, 1, req.NumRows())
require.Equal(t, fmt.Appendf(nil, "%d", ddlTableVer), req.GetRow(0).GetBytes(0))
require.NoError(t, r.Close())
dom.Close()
}
func TestTiDBHistoryTableConsistent(t *testing.T) {
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() {
require.NoError(t, store.Close())
}()
se := session.CreateSessionAndSetID(t, store)
query := `select (select group_concat(column_name) from information_schema.columns where table_name='tidb_background_subtask' order by ordinal_position)
= (select group_concat(column_name) from information_schema.columns where table_name='tidb_background_subtask_history' order by ordinal_position);`
r := session.MustExecToRecodeSet(t, se, query)
req := r.NewChunk(nil)
err := r.Next(ctx, req)
require.NoError(t, err)
require.Equal(t, 1, req.NumRows())
row := req.GetRow(0)
require.Equal(t, int64(1), row.GetInt64(0))
query = `select (select group_concat(column_name) from information_schema.columns where table_name='tidb_global_task' order by ordinal_position)
= (select group_concat(column_name) from information_schema.columns where table_name='tidb_global_task_history' order by ordinal_position);`
r = session.MustExecToRecodeSet(t, se, query)
req = r.NewChunk(nil)
err = r.Next(ctx, req)
require.NoError(t, err)
require.Equal(t, 1, req.NumRows())
row = req.GetRow(0)
require.Equal(t, int64(1), row.GetInt64(0))
dom.Close()
}
func TestANSISQLMode(t *testing.T) {
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
se := session.CreateSessionAndSetID(t, store)
session.MustExec(t, se, "USE mysql")
session.MustExec(t, se, `set @@global.sql_mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,ANSI"`)
session.MustExec(t, se, `delete from mysql.TiDB where VARIABLE_NAME="tidb_server_version"`)
store.SetOption(session.StoreBootstrappedKey, nil)
se.Close()
// Do some clean up, BootstrapSession will not create a new domain otherwise.
dom.Close()
// Set ANSI sql_mode and bootstrap again, to cover a bugfix.
// Once we have a SQL like that:
// select variable_value from mysql.tidb where variable_name = "system_tz"
// it fails to execute in the ANSI sql_mode, and makes TiDB cluster fail to bootstrap.
dom1, err := session.BootstrapSession(store)
require.NoError(t, err)
defer dom1.Close()
se = session.CreateSessionAndSetID(t, store)
session.MustExec(t, se, "select @@global.sql_mode")
se.Close()
}
func TestStmtSummary(t *testing.T) {
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
defer dom.Close()
se := session.CreateSessionAndSetID(t, store)
r := session.MustExecToRecodeSet(t, se, "select variable_value from mysql.global_variables where variable_name='tidb_enable_stmt_summary'")
req := r.NewChunk(nil)
require.NoError(t, r.Next(ctx, req))
row := req.GetRow(0)
require.Equal(t, []byte("ON"), row.GetBytes(0))
require.NoError(t, r.Close())
}
func TestReferencesPrivilegeOnColumn(t *testing.T) {
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
defer dom.Close()
se := session.CreateSessionAndSetID(t, store)
defer func() {
session.MustExec(t, se, "drop user if exists issue28531")
session.MustExec(t, se, "drop table if exists t1")
}()
session.MustExec(t, se, "create user if not exists issue28531")
session.MustExec(t, se, "use test")
session.MustExec(t, se, "drop table if exists t1")
session.MustExec(t, se, "create table t1 (a int)")
session.MustExec(t, se, "GRANT select (a), update (a),insert(a), references(a) on t1 to issue28531")
}
func TestTiDBEnablePagingVariable(t *testing.T) {
store, dom := session.CreateStoreAndBootstrap(t)
se := session.CreateSessionAndSetID(t, store)
defer func() { require.NoError(t, store.Close()) }()
defer dom.Close()
for _, sql := range []string{
"select @@global.tidb_enable_paging",
"select @@session.tidb_enable_paging",
} {
r := session.MustExecToRecodeSet(t, se, sql)
require.NotNil(t, r)
req := r.NewChunk(nil)
err := r.Next(context.Background(), req)
require.NoError(t, err)
require.NotEqual(t, 0, req.NumRows())
rows := statistics.RowToDatums(req.GetRow(0), r.Fields())
if vardef.DefTiDBEnablePaging {
match(t, rows, "1")
} else {
match(t, rows, "0")
}
r.Close()
}
}
func TestDDLTableCreateDDLNotifierTable(t *testing.T) {
testfailpoint.Enable(t, "github.com/pingcap/tidb/pkg/ddl/skipCheckReservedSchemaObjInNextGen", "return(true)")
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
se := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
ver, err := m.GetDDLTableVersion()
require.NoError(t, err)
require.GreaterOrEqual(t, ver, meta.DDLNotifierTableVersion)
// downgrade DDL table version
m.SetDDLTableVersion(meta.BackfillTableVersion)
session.MustExec(t, se, "drop table mysql.tidb_ddl_notifier")
err = txn.Commit(context.Background())
require.NoError(t, err)
// to upgrade session for create ddl notifier table
dom.Close()
dom, err = session.BootstrapSession(store)
require.NoError(t, err)
se = session.CreateSessionAndSetID(t, store)
session.MustExec(t, se, "select * from mysql.tidb_ddl_notifier")
dom.Close()
}
func TestIssue17979_1(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// test issue 20900, upgrade from v3.0 to v4.0.11+
seV3 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(58))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV3, 58)
session.MustExec(t, seV3, "delete from mysql.tidb where variable_name='default_oom_action'")
session.MustExec(t, seV3, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV3)
require.NoError(t, err)
require.Equal(t, int64(58), ver)
dom.Close()
domV4, err := session.BootstrapSession(store)
require.NoError(t, err)
seV4 := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seV4)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
r := session.MustExecToRecodeSet(t, seV4, "select variable_value from mysql.tidb where variable_name='default_oom_action'")
req := r.NewChunk(nil)
require.NoError(t, r.Next(ctx, req))
require.Equal(t, vardef.OOMActionLog, req.GetRow(0).GetString(0))
domV4.Close()
}
func TestIssue17979_2(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// test issue 20900, upgrade from v4.0.11 to v4.0.11
seV3 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(59))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV3, 59)
session.MustExec(t, seV3, "delete from mysql.tidb where variable_name='default_iim_action'")
session.MustExec(t, seV3, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV3)
require.NoError(t, err)
require.Equal(t, int64(59), ver)
dom.Close()
domV4, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domV4.Close()
seV4 := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seV4)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
r := session.MustExecToRecodeSet(t, seV4, "select variable_value from mysql.tidb where variable_name='default_oom_action'")
req := r.NewChunk(nil)
require.NoError(t, r.Next(ctx, req))
require.Equal(t, 0, req.NumRows())
}
// TestIssue20900_2 tests that a user can upgrade from TiDB 2.1 to latest,
// and their configuration remains similar. This helps protect against the
// case that a user had a 32G query memory limit in 2.1, but it is now a 1G limit
// in TiDB 4.0+. I tested this process, and it does correctly upgrade from 2.1 -> 4.0,
// but from 4.0 -> 5.0, the new default is picked up.
func TestIssue20900_2(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// test issue 20900, upgrade from v4.0.8 to v4.0.9+
seV3 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(52))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV3, 52)
session.MustExec(t, seV3, "delete from mysql.tidb where variable_name='default_memory_quota_query'")
session.MustExec(t, seV3, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV3)
require.NoError(t, err)
require.Equal(t, int64(52), ver)
dom.Close()
domV4, err := session.BootstrapSession(store)
require.NoError(t, err)
seV4 := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seV4)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
r := session.MustExecToRecodeSet(t, seV4, "select @@tidb_mem_quota_query")
req := r.NewChunk(nil)
require.NoError(t, r.Next(ctx, req))
require.Equal(t, "1073741824", req.GetRow(0).GetString(0))
require.Equal(t, int64(1073741824), seV4.GetSessionVars().MemQuotaQuery)
r = session.MustExecToRecodeSet(t, seV4, "select variable_value from mysql.tidb where variable_name='default_memory_quota_query'")
req = r.NewChunk(nil)
require.NoError(t, r.Next(ctx, req))
require.Equal(t, 0, req.NumRows())
domV4.Close()
}
func TestUpgradeClusteredIndexDefaultValue(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
seV67 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(67))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV67, 67)
session.MustExec(t, seV67, "UPDATE mysql.global_variables SET VARIABLE_VALUE = 'OFF' where VARIABLE_NAME = 'tidb_enable_clustered_index'")
require.Equal(t, uint64(1), seV67.GetSessionVars().StmtCtx.AffectedRows())
session.MustExec(t, seV67, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV67)
require.NoError(t, err)
require.Equal(t, int64(67), ver)
dom.Close()
domV68, err := session.BootstrapSession(store)
require.NoError(t, err)
seV68 := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seV68)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
r := session.MustExecToRecodeSet(t, seV68, `select @@global.tidb_enable_clustered_index, @@session.tidb_enable_clustered_index`)
req := r.NewChunk(nil)
require.NoError(t, r.Next(context.Background(), req))
require.Equal(t, 1, req.NumRows())
row := req.GetRow(0)
require.Equal(t, "ON", row.GetString(0))
require.Equal(t, "ON", row.GetString(1))
domV68.Close()
}
func TestAnalyzeVersionUpgradeFrom300To500(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// Upgrade from 3.0.0 to 5.1+ or above.
ver300 := 33
seV3 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(ver300))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV3, ver300)
session.MustExec(t, seV3, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBAnalyzeVersion))
session.MustExec(t, seV3, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV3)
require.NoError(t, err)
require.Equal(t, int64(ver300), ver)
// We are now in 3.0.0, check tidb_analyze_version should not exist.
res := session.MustExecToRecodeSet(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBAnalyzeVersion))
chk := res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 0, chk.NumRows())
dom.Close()
domCurVer, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
// We are now in version no lower than 5.x, tidb_enable_index_merge should be 1.
res = session.MustExecToRecodeSet(t, seCurVer, "select @@tidb_analyze_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 TestIndexMergeUpgradeFrom300To540(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// Upgrade from 3.0.0 to 5.4+.
ver300 := 33
seV3 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(ver300))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV3, ver300)
session.MustExec(t, seV3, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBEnableIndexMerge))
session.MustExec(t, seV3, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV3)
require.NoError(t, err)
require.Equal(t, int64(ver300), ver)
// We are now in 3.0.0, check tidb_enable_index_merge should not exist.
res := session.MustExecToRecodeSet(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBEnableIndexMerge))
chk := res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 0, chk.NumRows())
dom.Close()
domCurVer, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
// We are now in 5.x, tidb_enable_index_merge should be off.
res = session.MustExecToRecodeSet(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))
}
// We set tidb_enable_index_merge as on.
// And after upgrade to 5.x, tidb_enable_index_merge should remains to be on.
func TestIndexMergeUpgradeFrom400To540Enable(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
testIndexMergeUpgradeFrom400To540(t, true)
}
func TestIndexMergeUpgradeFrom400To540Disable(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
testIndexMergeUpgradeFrom400To540(t, false)
}
func testIndexMergeUpgradeFrom400To540(t *testing.T, enable bool) {
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// upgrade from 4.0.0 to 5.4+.
ver400 := 46
seV4 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(ver400))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV4, ver400)
session.MustExec(t, seV4, fmt.Sprintf("update mysql.GLOBAL_VARIABLES set variable_value='%s' where variable_name='%s'", vardef.Off, vardef.TiDBEnableIndexMerge))
session.MustExec(t, seV4, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.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 := session.MustExecToRecodeSet(t, seV4, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.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, vardef.Off, row.GetString(1))
if enable {
// 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.
session.MustExec(t, seV4, "set global tidb_enable_index_merge = on")
}
dom.Close()
// Upgrade to 5.x.
domCurVer, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
// We are now in 5.x, tidb_enable_index_merge should be on because we enable it in 4.0.0.
res = session.MustExecToRecodeSet(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 enable {
require.Equal(t, int64(1), row.GetInt64(0))
} else {
require.Equal(t, int64(0), row.GetInt64(0))
}
}
func TestTiDBOptRangeMaxSizeWhenUpgrading(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// Upgrade from v6.3.0 to v6.4.0+.
ver94 := 94
seV630 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(ver94))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV630, ver94)
session.MustExec(t, seV630, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBOptRangeMaxSize))
session.MustExec(t, seV630, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV630)
require.NoError(t, err)
require.Equal(t, int64(ver94), ver)
// We are now in 6.3.0, check tidb_opt_range_max_size should not exist.
res := session.MustExecToRecodeSet(t, seV630, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBOptRangeMaxSize))
chk := res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 0, chk.NumRows())
dom.Close()
domCurVer, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
// We are now in version no lower than v6.4.0, tidb_opt_range_max_size should be 0.
res = session.MustExecToRecodeSet(t, seCurVer, "select @@session.tidb_opt_range_max_size")
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, "0", row.GetString(0))
res = session.MustExecToRecodeSet(t, seCurVer, "select @@global.tidb_opt_range_max_size")
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, "0", row.GetString(0))
}
func TestTiDBOptAdvancedJoinHintWhenUpgrading(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// Upgrade from v6.6.0 to v7.0.0+.
ver134 := 134
seV660 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(ver134))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV660, ver134)
session.MustExec(t, seV660, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBOptAdvancedJoinHint))
session.MustExec(t, seV660, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV660)
require.NoError(t, err)
require.Equal(t, int64(ver134), ver)
// We are now in 6.6.0, check tidb_opt_advanced_join_hint should not exist.
res := session.MustExecToRecodeSet(t, seV660, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBOptAdvancedJoinHint))
chk := res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 0, chk.NumRows())
dom.Close()
domCurVer, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
// We are now in version no lower than v7.0.0, tidb_opt_advanced_join_hint should be false.
res = session.MustExecToRecodeSet(t, seCurVer, "select @@session.tidb_opt_advanced_join_hint;")
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))
res = session.MustExecToRecodeSet(t, seCurVer, "select @@global.tidb_opt_advanced_join_hint;")
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 TestTiDBCostModelUpgradeFrom300To650(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// Upgrade from 3.0.0 to 6.5+.
ver300 := 33
seV3 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(ver300))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV3, ver300)
session.MustExec(t, seV3, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBCostModelVersion))
session.MustExec(t, seV3, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.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 := session.MustExecToRecodeSet(t, seV3, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBCostModelVersion))
chk := res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 0, chk.NumRows())
dom.Close()
domCurVer, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
// We are now in 6.5+, TiDBCostModelVersion should be 1.
res = session.MustExecToRecodeSet(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) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
for i := range 2 {
func() {
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// upgrade from 6.1 to 6.5+.
ver61 := 91
seV61 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(ver61))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV61, ver61)
session.MustExec(t, seV61, fmt.Sprintf("update mysql.GLOBAL_VARIABLES set variable_value='%s' where variable_name='%s'", "1", vardef.TiDBCostModelVersion))
session.MustExec(t, seV61, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.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 := session.MustExecToRecodeSet(t, seV61, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.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))
res.Close()
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.
session.MustExec(t, seV61, "set global tidb_cost_model_version = 2")
}
dom.Close()
// Upgrade to 6.5.
domCurVer, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
// We are now in 6.5.
res = session.MustExecToRecodeSet(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))
}
res.Close()
}()
}
}
func TestIndexJoinMultiPatternByUpgrade650To840(t *testing.T) {
if kerneltype.IsNextGen() {
t.Skip("Skip this case because there is no upgrade in the first release of next-gen kernel")
}
ctx := context.Background()
store, dom := session.CreateStoreAndBootstrap(t)
defer func() { require.NoError(t, store.Close()) }()
// Upgrade from 6.5.0 to 8.4+ or above.
ver650 := 109
seV7 := session.CreateSessionAndSetID(t, store)
txn, err := store.Begin()
require.NoError(t, err)
m := meta.NewMutator(txn)
err = m.FinishBootstrap(int64(ver650))
require.NoError(t, err)
err = txn.Commit(context.Background())
require.NoError(t, err)
session.RevertVersionAndVariables(t, seV7, ver650)
session.MustExec(t, seV7, fmt.Sprintf("delete from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBEnableINLJoinInnerMultiPattern))
session.MustExec(t, seV7, "commit")
store.SetOption(session.StoreBootstrappedKey, nil)
ver, err := session.GetBootstrapVersion(seV7)
require.NoError(t, err)
require.Equal(t, int64(ver650), ver)
// We are now in 6.5.0, check tidb_enable_inl_join_inner_multi_pattern should not exist.
res := session.MustExecToRecodeSet(t, seV7, fmt.Sprintf("select * from mysql.GLOBAL_VARIABLES where variable_name='%s'", vardef.TiDBEnableINLJoinInnerMultiPattern))
chk := res.NewChunk(nil)
err = res.Next(ctx, chk)
require.NoError(t, err)
require.Equal(t, 0, chk.NumRows())
dom.Close()
domCurVer, err := session.BootstrapSession(store)
require.NoError(t, err)
defer domCurVer.Close()
seCurVer := session.CreateSessionAndSetID(t, store)
ver, err = session.GetBootstrapVersion(seCurVer)
require.NoError(t, err)
require.Equal(t, session.CurrentBootstrapVersion, ver)
// We are now in version no lower than 8.4, tidb_enable_inl_join_inner_multi_pattern be off.
res = session.MustExecToRecodeSet(t, seCurVer, "select @@global.tidb_enable_inl_join_inner_multi_pattern")
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))
}