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

*: let our unit test cover the infoschema v2 code #52156

Merged
merged 13 commits into from
Apr 12, 2024
8 changes: 4 additions & 4 deletions pkg/ddl/db_rename_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,11 @@ func TestRenameConcurrentAutoID(t *testing.T) {
store := testkit.CreateMockStore(t, mockstore.WithDDLChecker())

tk1 := testkit.NewTestKit(t, store)
tk2 := testkit.NewTestKit(t, store)
tk3 := testkit.NewTestKit(t, store)
tk1.MustExec("use test")
tk2.MustExec(`use test`)
tk3.MustExec(`use test`)
// Use first client session, tidb1
tk1.MustExec(`create schema if not exists test1`)
tk1.MustExec(`create schema if not exists test2`)
Expand All @@ -315,14 +319,11 @@ func TestRenameConcurrentAutoID(t *testing.T) {
require.Equal(t, int64(5), origAllocs.Allocs[0].End())

// Switch to a new client (tidb2)
tk2 := testkit.NewTestKit(t, store)
tk2.MustExec(`use test`)
alterChan := make(chan error)
go func() {
// will wait for tidb1
alterChan <- tk2.ExecToErr(`rename table test1.t1 to test2.t2`)
}()
tk3 := testkit.NewTestKit(t, store)
waitFor := func(tableName, s string, pos int) {
for {
select {
Expand All @@ -344,7 +345,6 @@ func TestRenameConcurrentAutoID(t *testing.T) {

// Switch to new client (tidb3)
waitFor("t1", "public", 4)
tk3.MustExec(`use test`)
tk3.MustExec(`begin`)
tk3.MustExec(`insert into test2.t2 values (null, "t2 first null")`)
tk3.MustQuery(`select _tidb_rowid, a, b from test2.t2`).Sort().Check(testkit.Rows("4 3 t2 first null"))
Expand Down
9 changes: 4 additions & 5 deletions pkg/ddl/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,20 +351,19 @@ func testCheckJobCancelled(t *testing.T, store kv.Storage, job *model.Job, state
func TestRenameTableAutoIDs(t *testing.T) {
store := testkit.CreateMockStore(t)
tk1 := testkit.NewTestKit(t, store)

tk2 := testkit.NewTestKit(t, store)
tk3 := testkit.NewTestKit(t, store)
dbName := "RenameTableAutoIDs"
tk1.MustExec(`create schema ` + dbName)
tk1.MustExec(`create schema ` + dbName + "2")
tk1.MustExec(`use ` + dbName)
tk2.MustExec(`use ` + dbName)
tk3.MustExec(`use ` + dbName)
tk1.MustExec(`CREATE TABLE t (a int auto_increment primary key nonclustered, b varchar(255), key (b)) AUTO_ID_CACHE 100`)
tk1.MustExec(`insert into t values (11,11),(2,2),(null,12)`)
tk1.MustExec(`insert into t values (null,18)`)
tk1.MustQuery(`select _tidb_rowid, a, b from t`).Sort().Check(testkit.Rows("13 11 11", "14 2 2", "15 12 12", "17 16 18"))

tk2 := testkit.NewTestKit(t, store)
tk2.MustExec(`use ` + dbName)
tk3 := testkit.NewTestKit(t, store)
tk3.MustExec(`use ` + dbName)
waitFor := func(col int, tableName, s string) {
for {
tk4 := testkit.NewTestKit(t, store)
Expand Down
5 changes: 5 additions & 0 deletions pkg/ddl/tests/fail/fail_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,11 @@ func TestRunDDLJobPanic(t *testing.T) {
func TestPartitionAddIndexGC(t *testing.T) {
s := createFailDBSuite(t)
tk := testkit.NewTestKit(t, s.store)
if tk.MustQuery("select @@tidb_schema_cache_size > 0").Equal(testkit.Rows("1")) {
// This test mock GC expire time exceeded, it's ok for infoschema v1 because it does not visit the network.
// While in infoschema v2, SchemaTable call meta.ListTables and fail.
t.Skip()
}
tk.MustExec("use test")
tk.MustExec(`create table partition_add_idx (
id int not null,
Expand Down
12 changes: 6 additions & 6 deletions pkg/ddl/tests/partition/db_partition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2105,7 +2105,6 @@ func TestExchangePartitionHook(t *testing.T) {
func TestExchangePartitionAutoID(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)

tk.MustExec("set @@tidb_enable_exchange_partition=1")
defer tk.MustExec("set @@tidb_enable_exchange_partition=0")

Expand Down Expand Up @@ -3178,20 +3177,21 @@ func TestRemoveListColumnsPartitioning(t *testing.T) {

func TestRemovePartitioningAutoIDs(t *testing.T) {
store := testkit.CreateMockStore(t)
dbName := "RemovePartAutoIDs"
tk1 := testkit.NewTestKit(t, store)
tk2 := testkit.NewTestKit(t, store)
tk3 := testkit.NewTestKit(t, store)

dbName := "RemovePartAutoIDs"
tk1.MustExec(`create schema ` + dbName)
tk1.MustExec(`use ` + dbName)
tk2.MustExec(`use ` + dbName)
tk3.MustExec(`use ` + dbName)

tk1.MustExec(`CREATE TABLE t (a int auto_increment primary key nonclustered, b varchar(255), key (b)) partition by hash(a) partitions 3`)
tk1.MustExec(`insert into t values (11,11),(2,2),(null,12)`)
tk1.MustExec(`insert into t values (null,18)`)
tk1.MustQuery(`select _tidb_rowid, a, b from t`).Sort().Check(testkit.Rows("13 11 11", "14 2 2", "15 12 12", "17 16 18"))

tk2 := testkit.NewTestKit(t, store)
tk2.MustExec(`use ` + dbName)
tk3 := testkit.NewTestKit(t, store)
tk3.MustExec(`use ` + dbName)
waitFor := func(col int, tableName, s string) {
for {
tk4 := testkit.NewTestKit(t, store)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func TestRoleBasic(t *testing.T) {

testutil.RegisterTaskMeta(t, c.MockCtrl, testutil.GetMockBasicSchedulerExt(c.MockCtrl), c.TestContext, nil)
tk := testkit.NewTestKit(t, c.Store)
tk.MustExec("set @@global.tidb_schema_cache_size = default")

// 1. all "" role.
submitTaskAndCheckSuccessForBasic(c.Ctx, t, "😁", c.TestContext)
Expand Down
9 changes: 6 additions & 3 deletions pkg/disttask/framework/storage/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,6 @@ func TestSubTaskTable(t *testing.T) {
ok, err = sm.HasSubtasksInStates(ctx, "tidb1", 1, proto.StepOne, proto.SubtaskStatePending)
require.NoError(t, err)
require.False(t, ok)

require.NoError(t, testutil.DeleteSubtasksByTaskID(ctx, sm, 1))

ok, err = sm.HasSubtasksInStates(ctx, "tidb1", 1, proto.StepOne, proto.SubtaskStatePending, proto.SubtaskStateRunning)
Expand All @@ -560,7 +559,11 @@ func TestSubTaskTable(t *testing.T) {
require.NoError(t, err)
require.Len(t, subtasks, 0)

require.NoError(t, sm.FinishSubtask(ctx, "tidb1", 2, []byte{}))
subtasks, err = testutil.GetSubtasksByTaskID(ctx, sm, 2)
require.NoError(t, err)
require.Len(t, subtasks, 1)
subtaskID := subtasks[0].ID
require.NoError(t, sm.FinishSubtask(ctx, "tidb1", subtaskID, []byte{}))

subtasks, err = sm.GetAllSubtasksByStepAndState(ctx, 2, proto.StepOne, proto.SubtaskStateSucceed)
require.NoError(t, err)
Expand All @@ -569,7 +572,7 @@ func TestSubTaskTable(t *testing.T) {
rowCount, err := sm.GetSubtaskRowCount(ctx, 2, proto.StepOne)
require.NoError(t, err)
require.Equal(t, int64(0), rowCount)
require.NoError(t, sm.UpdateSubtaskRowCount(ctx, 2, 100))
require.NoError(t, sm.UpdateSubtaskRowCount(ctx, subtaskID, 100))
rowCount, err = sm.GetSubtaskRowCount(ctx, 2, proto.StepOne)
require.NoError(t, err)
require.Equal(t, int64(100), rowCount)
Expand Down
16 changes: 8 additions & 8 deletions pkg/disttask/framework/storage/task_state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestTaskState(t *testing.T) {
// 1. cancel task
id, err := gm.CreateTask(ctx, "key1", "test", 4, []byte("test"))
require.NoError(t, err)
require.Equal(t, int64(1), id)
// require.Equal(t, int64(1), id) TODO: unstable for infoschema v2
require.NoError(t, gm.CancelTask(ctx, id))
task, err := gm.GetTaskByID(ctx, id)
require.NoError(t, err)
Expand All @@ -43,7 +43,7 @@ func TestTaskState(t *testing.T) {
// 2. cancel task by key session
id, err = gm.CreateTask(ctx, "key2", "test", 4, []byte("test"))
require.NoError(t, err)
require.Equal(t, int64(2), id)
// require.Equal(t, int64(2), id) TODO: unstable for infoschema v2
require.NoError(t, gm.WithNewTxn(ctx, func(se sessionctx.Context) error {
ctx = util.WithInternalSourceType(ctx, kv.InternalDistTask)
return gm.CancelTaskByKeySession(ctx, se, "key2")
Expand All @@ -55,7 +55,7 @@ func TestTaskState(t *testing.T) {
// 3. fail task
id, err = gm.CreateTask(ctx, "key3", "test", 4, []byte("test"))
require.NoError(t, err)
require.Equal(t, int64(3), id)
// require.Equal(t, int64(3), id) TODO: unstable for infoschema v2
failedErr := errors.New("test err")
require.NoError(t, gm.FailTask(ctx, id, proto.TaskStatePending, failedErr))
task, err = gm.GetTaskByID(ctx, id)
Expand All @@ -66,7 +66,7 @@ func TestTaskState(t *testing.T) {
// 4. Reverted task
id, err = gm.CreateTask(ctx, "key4", "test", 4, []byte("test"))
require.NoError(t, err)
require.Equal(t, int64(4), id)
// require.Equal(t, int64(4), id) TODO: unstable for infoschema v2
task, err = gm.GetTaskByID(ctx, 4)
require.NoError(t, err)
checkTaskStateStep(t, task, proto.TaskStatePending, proto.StepInit)
Expand All @@ -84,7 +84,7 @@ func TestTaskState(t *testing.T) {
// 5. pause task
id, err = gm.CreateTask(ctx, "key5", "test", 4, []byte("test"))
require.NoError(t, err)
require.Equal(t, int64(5), id)
// require.Equal(t, int64(5), id) TODO: unstable for infoschema v2
found, err := gm.PauseTask(ctx, "key5")
require.NoError(t, err)
require.True(t, found)
Expand Down Expand Up @@ -113,12 +113,12 @@ func TestTaskState(t *testing.T) {
// 8. succeed task
id, err = gm.CreateTask(ctx, "key6", "test", 4, []byte("test"))
require.NoError(t, err)
require.Equal(t, int64(6), id)
task, err = gm.GetTaskByID(ctx, 6)
// require.Equal(t, int64(6), id) TODO: unstable for infoschema v2
task, err = gm.GetTaskByID(ctx, id)
require.NoError(t, err)
checkTaskStateStep(t, task, proto.TaskStatePending, proto.StepInit)
require.NoError(t, gm.SwitchTaskStep(ctx, task, proto.TaskStateRunning, proto.StepOne, nil))
task, err = gm.GetTaskByID(ctx, 6)
task, err = gm.GetTaskByID(ctx, id)
require.NoError(t, err)
checkTaskStateStep(t, task, proto.TaskStateRunning, proto.StepOne)
require.NoError(t, gm.SucceedTask(ctx, id))
Expand Down
30 changes: 14 additions & 16 deletions pkg/executor/infoschema_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -1765,20 +1765,18 @@ func keyColumnUsageInTable(schema model.CIStr, table *model.TableInfo) [][]types
return rows
}

func ensureSchemaTables(is infoschema.InfoSchema, schemas []*model.DBInfo) []*model.DBInfo {
res := schemas[:0]
for _, db := range schemas {
if len(db.Tables) == 0 {
// For infoschema v2, Tables of DBInfo could be missing.
dbInfo := db.Clone()
tbls := is.SchemaTables(db.Name)
for _, tbl := range tbls {
dbInfo.Tables = append(dbInfo.Tables, tbl.Meta())
}
res = append(res, dbInfo)
} else {
res = append(res, db)
}
func ensureSchemaTables(is infoschema.InfoSchema, schemaNames []model.CIStr) []*model.DBInfo {
// For infoschema v2, Tables of DBInfo could be missing.
res := make([]*model.DBInfo, 0, len(schemaNames))
for _, dbName := range schemaNames {
dbInfoRaw, _ := is.SchemaByName(dbName)
dbInfo := dbInfoRaw.Clone()
dbInfo.Tables = dbInfo.Tables[:0]
tbls := is.SchemaTables(dbName)
for _, tbl := range tbls {
dbInfo.Tables = append(dbInfo.Tables, tbl.Meta())
}
res = append(res, dbInfo)
}
return res
}
Expand Down Expand Up @@ -1824,8 +1822,8 @@ func (e *memtableRetriever) setDataForTiKVRegionStatus(ctx context.Context, sctx
return err
}
}
schemas := is.AllSchemas()
schemas = ensureSchemaTables(is, schemas)
schemaNames := is.AllSchemaNames()
schemas := ensureSchemaTables(is, schemaNames)
tableInfos := tikvHelper.GetRegionsTableInfo(allRegionsInfo, schemas)
for i := range allRegionsInfo.Regions {
regionTableList := tableInfos[allRegionsInfo.Regions[i].ID]
Expand Down
7 changes: 4 additions & 3 deletions pkg/executor/memtable_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -791,9 +791,10 @@ func (e *hotRegionsHistoryRetriver) retrieve(ctx context.Context, sctx sessionct
}
tz := sctx.GetSessionVars().Location()
is := sessiontxn.GetTxnManager(sctx).GetTxnInfoSchema()
allSchemas := is.AllSchemas()
schemas := tikvHelper.FilterMemDBs(allSchemas)
tables := tikvHelper.GetTablesInfoWithKeyRange(ensureSchemaTables(is, schemas))
allSchemaNames := is.AllSchemaNames()
schemas := ensureSchemaTables(is, allSchemaNames)
schemas = tikvHelper.FilterMemDBs(schemas)
tables := tikvHelper.GetTablesInfoWithKeyRange(schemas)
for e.heap.Len() > 0 && len(finalRows) < hotRegionsHistoryBatchSize {
minTimeItem := heap.Pop(e.heap).(hotRegionsResult)
rows, err := e.getHotRegionRowWithSchemaInfo(minTimeItem.messages.HistoryHotRegion[0], tikvHelper, tables, tz)
Expand Down
1 change: 0 additions & 1 deletion pkg/executor/test/ddl/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,6 @@ func TestRenameTable(t *testing.T) {
store := testkit.CreateMockStore(t, mockstore.WithDDLChecker())

tk := testkit.NewTestKit(t, store)

tk.MustExec("drop database if exists rename1")
tk.MustExec("drop database if exists rename2")
tk.MustExec("drop database if exists rename3")
Expand Down
2 changes: 1 addition & 1 deletion pkg/infoschema/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ func (b *Builder) InitWithOldInfoSchema(oldSchema InfoSchema) (*Builder, error)
// Do not mix infoschema v1 and infoschema v2 building, this can simplify the logic.
// If we want to build infoschema v2, but the old infoschema is v1, just return error to trigger a full load.
if b.enableV2 != IsV2(oldSchema) {
return nil, errors.New("builder's infoschema mismatch, return error to trigger full reload")
return nil, errors.Errorf("builder's (v2=%v) infoschema mismatch, return error to trigger full reload", b.enableV2)
}

if schemaV2, ok := oldSchema.(*infoschemaV2); ok {
Expand Down
7 changes: 7 additions & 0 deletions pkg/infoschema/infoschema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,13 @@ func TestBuildBundle(t *testing.T) {
assertBundle(is, tbl1.Meta().ID, tb1Bundle)
assertBundle(is, tbl2.Meta().ID, nil)
assertBundle(is, p1.ID, p1Bundle)

if len(db.Tables) == 0 {
tbls := is.SchemaTables(db.Name)
for _, tbl := range tbls {
db.Tables = append(db.Tables, tbl.Meta())
}
}
builder, err := infoschema.NewBuilder(dom, nil, infoschema.NewData()).InitWithDBInfos([]*model.DBInfo{db}, is.AllPlacementPolicies(), is.AllResourceGroups(), is.SchemaMetaVersion())
require.NoError(t, err)
is2 := builder.Build(math.MaxUint64)
Expand Down
2 changes: 0 additions & 2 deletions pkg/infoschema/test/infoschemav2test/v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@ import (
)

func TestSpecialSchemas(t *testing.T) {
t.Skip("This feature is not enabled yet")
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil, nil))
tk.MustExec("use test")

tk.MustQuery("select @@global.tidb_schema_cache_size;").Check(testkit.Rows("0"))
tk.MustExec("set @@global.tidb_schema_cache_size = 1024;")
tk.MustQuery("select @@global.tidb_schema_cache_size;").Check(testkit.Rows("1024"))
tk.MustExec("create table t (id int);")
Expand Down
4 changes: 4 additions & 0 deletions pkg/planner/core/binary_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ func TestTooLongBinaryPlan(t *testing.T) {
require.NoError(t, logutil.InitLogger(newCfg.Log.ToLogConfig()))
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
if tk.MustQuery("select @@tidb_schema_cache_size > 0").Equal(testkit.Rows("1")) {
t.Skip("TODO: the performance is poor for this test under infoschema v2")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#52479 optimize the performance here, after that we do not need to skip.

}

require.NoError(t, tk.Session().Auth(&auth.UserIdentity{Username: "root", Hostname: "%"}, nil, nil, nil))
tk.MustExec(fmt.Sprintf("set @@tidb_slow_query_file='%v'", f.Name()))

Expand Down
1 change: 0 additions & 1 deletion pkg/sessionctx/variable/noop.go
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,6 @@ var noopSysVars = []*SysVar{
{Scope: ScopeGlobal, Name: ThreadPoolSize, Value: "16", Type: TypeUnsigned, MinValue: 1, MaxValue: 64},
{Scope: ScopeNone, Name: "lower_case_file_system", Value: "1"},
{Scope: ScopeNone, Name: LowerCaseTableNames, Value: "2"},
{Scope: ScopeGlobal, Name: TiDBSchemaCacheSize, Value: "0"},

// for compatibility purpose, we should leave them alone.
// TODO: Follow the Terminology Updates of MySQL after their changes arrived.
Expand Down
8 changes: 8 additions & 0 deletions pkg/sessionctx/variable/sysvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -3086,6 +3086,14 @@ var defaultSysVars = []*SysVar{
}, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) {
return BoolToOnOff(EnableCheckConstraint.Load()), nil
}},
{Scope: ScopeGlobal, Name: TiDBSchemaCacheSize, Value: strconv.Itoa(DefTiDBSchemaCacheSize), Type: TypeInt, MinValue: 0, MaxValue: math.MaxInt32, SetGlobal: func(ctx context.Context, vars *SessionVars, val string) error {
// It does not take effect immediately, but within a ddl lease, infoschema reload would cause the v2 to be used.
SchemaCacheSize.Store(TidbOptInt64(val, DefTiDBSchemaCacheSize))
return nil
}, GetGlobal: func(ctx context.Context, vars *SessionVars) (string, error) {
val := SchemaCacheSize.Load()
return strconv.FormatInt(val, 10), nil
}},
{Scope: ScopeSession, Name: TiDBSessionAlias, Value: "", Type: TypeStr,
Validation: func(s *SessionVars, normalizedValue string, originalValue string, _ ScopeFlag) (string, error) {
chars := []rune(normalizedValue)
Expand Down
14 changes: 14 additions & 0 deletions pkg/testkit/testkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package testkit
import (
"context"
"fmt"
"math/rand"
"net"
"net/http"
"net/http/pprof"
Expand Down Expand Up @@ -116,6 +117,19 @@ func NewTestKitWithSession(t testing.TB, store kv.Storage, se sessiontypes.Sessi
// RefreshSession set a new session for the testkit
func (tk *TestKit) RefreshSession() {
tk.session = NewSession(tk.t, tk.store)

if intest.InTest {
eb, ok := tk.store.(kv.EtcdBackend)
if ok { // Only for unit test now
addrs, err := eb.EtcdAddrs()
if err == nil && len(addrs) > 0 {
if rand.Intn(10) > 3 { // 70% chance to run infoschema v2
tk.MustExec("set @@global.tidb_schema_cache_size = 1024")
}
}
}
}

// enforce sysvar cache loading, ref loadCommonGlobalVariableIfNeeded
tk.MustExec("select 3")
}
Expand Down