From 46cb7bb6ce25a9774a63c18b0b9b5591a5bbe285 Mon Sep 17 00:00:00 2001 From: tangenta Date: Mon, 11 Nov 2024 17:48:39 +0800 Subject: [PATCH 1/5] infoschema: don't load table info to get auto_increment value --- pkg/executor/infoschema_reader.go | 20 ++++++++++++++- pkg/infoschema/infoschema_v2.go | 25 +++++++++++++++++++ .../test/infoschemav2test/v2_test.go | 24 ++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/pkg/executor/infoschema_reader.go b/pkg/executor/infoschema_reader.go index be1237d4b3bdb..d60e18d66b5b4 100644 --- a/pkg/executor/infoschema_reader.go +++ b/pkg/executor/infoschema_reader.go @@ -242,11 +242,29 @@ func getAutoIncrementID( sctx sessionctx.Context, tblInfo *model.TableInfo, ) int64 { + if raw, ok := is.(*infoschema.SessionExtendedInfoSchema); ok { + v2, ok := raw.InfoSchema.(interface { + TableIsCached(id int64) bool + }) + if ok { + isCached := v2.TableIsCached(tblInfo.ID) + if !isCached { + // Loading table info from kv storage invalidates the cached auto_increment id. + return 0 + } + } + } tbl, ok := is.TableByID(context.Background(), tblInfo.ID) if !ok { return 0 } - return tbl.Allocators(sctx.GetTableCtx()).Get(autoid.AutoIncrementType).Base() + 1 + alloc := tbl.Allocators(sctx.GetTableCtx()).Get(autoid.AutoIncrementType) + if alloc == nil || alloc.Base() == 0 { + // It may not be loaded yet. + // To show global next autoID, one should use `show table x next_row_id`. + return 0 + } + return alloc.Base() + 1 } func hasPriv(ctx sessionctx.Context, priv mysql.PrivilegeType) bool { diff --git a/pkg/infoschema/infoschema_v2.go b/pkg/infoschema/infoschema_v2.go index 749c3ccf9f705..4f732031d94ed 100644 --- a/pkg/infoschema/infoschema_v2.go +++ b/pkg/infoschema/infoschema_v2.go @@ -691,6 +691,31 @@ func (is *infoschemaV2) IterateAllTableItems(visit func(TableItem) bool) { }) } +// TableIsCached checks whether the table is cached. +func (is *infoschemaV2) TableIsCached(id int64) (ok bool) { + if !tableIDIsValid(id) { + return false + } + + itm, ok := is.searchTableItemByID(id) + if !ok { + return false + } + + if isTableVirtual(id) { + if raw, exist := is.Data.specials.Load(itm.dbName.L); exist { + schTbls := raw.(*schemaTables) + _, ok = schTbls.tables[itm.tableName.L] + return ok + } + return false + } + + key := tableCacheKey{itm.tableID, itm.schemaVersion} + tbl, found := is.tableCache.Get(key) + return found && tbl != nil +} + // IsSpecialDB tells whether the database is a special database. func IsSpecialDB(dbName string) bool { return dbName == util.InformationSchemaName.L || diff --git a/pkg/infoschema/test/infoschemav2test/v2_test.go b/pkg/infoschema/test/infoschemav2test/v2_test.go index f44556c9f09ef..132e2d0642431 100644 --- a/pkg/infoschema/test/infoschemav2test/v2_test.go +++ b/pkg/infoschema/test/infoschemav2test/v2_test.go @@ -28,6 +28,7 @@ import ( "github.com/pingcap/tidb/pkg/domain/infosync" "github.com/pingcap/tidb/pkg/infoschema" infoschemacontext "github.com/pingcap/tidb/pkg/infoschema/context" + "github.com/pingcap/tidb/pkg/meta/autoid" "github.com/pingcap/tidb/pkg/parser/auth" "github.com/pingcap/tidb/pkg/parser/model" "github.com/pingcap/tidb/pkg/sessionctx/variable" @@ -534,3 +535,26 @@ func TestSnapshotInfoschemaReader(t *testing.T) { sql = fmt.Sprintf("select * from INFORMATION_SCHEMA.TABLES as of timestamp '%s' where table_schema = 'issue55827'", timeStr) tk.MustQuery(sql).Check(testkit.Rows()) } + +func TestInfoSchemaCachedAutoIncrement(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + autoid.SetStep(1) + tk.MustExec("set @@global.tidb_schema_cache_size = 0;") + tk.MustExec("create table t (a int primary key auto_increment);") + autoIncQuery := "select auto_increment from information_schema.tables where table_name = 't' and table_schema = 'test';" + + tk.MustQuery(autoIncQuery).Check(testkit.Rows("0")) + tk.MustExec("insert into t values (),(),();") + tk.MustQuery(autoIncQuery).Check(testkit.Rows("4")) + + tk.MustExec("set @@global.tidb_schema_cache_size = 1024 * 1024 * 1024;") + tk.MustExec("create table t1 (a int);") // trigger infoschema cache reload + tk.MustQuery(autoIncQuery).Check(testkit.Rows("0")) + tk.MustExec("insert into t values ();") + tk.MustQuery(autoIncQuery).Check(testkit.Rows("5")) + tk.MustExec("set @@global.tidb_schema_cache_size = 0;") + tk.MustExec("drop table t1;") // trigger infoschema cache reload + tk.MustQuery(autoIncQuery).Check(testkit.Rows("0")) +} From ef06307ec5cb2192ead9b8bbf8c9a068540e46ae Mon Sep 17 00:00:00 2001 From: tangenta Date: Mon, 11 Nov 2024 18:08:54 +0800 Subject: [PATCH 2/5] update bazel --- pkg/infoschema/test/infoschemav2test/BUILD.bazel | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/infoschema/test/infoschemav2test/BUILD.bazel b/pkg/infoschema/test/infoschemav2test/BUILD.bazel index b49117d2f6fde..ebfa163c612f1 100644 --- a/pkg/infoschema/test/infoschemav2test/BUILD.bazel +++ b/pkg/infoschema/test/infoschemav2test/BUILD.bazel @@ -8,12 +8,13 @@ go_test( "v2_test.go", ], flaky = True, - shard_count = 11, + shard_count = 12, deps = [ "//pkg/domain", "//pkg/domain/infosync", "//pkg/infoschema", "//pkg/infoschema/context", + "//pkg/meta/autoid", "//pkg/parser/auth", "//pkg/parser/model", "//pkg/sessionctx/variable", From fbe0fd220739f96a2943269a680123fd820963e1 Mon Sep 17 00:00:00 2001 From: cbcwestwolf <1004626265@qq.com> Date: Mon, 11 Nov 2024 20:51:55 +0800 Subject: [PATCH 3/5] optimize GetDataAndIndexLength --- .../handle/cache/stats_table_row_cache.go | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/pkg/statistics/handle/cache/stats_table_row_cache.go b/pkg/statistics/handle/cache/stats_table_row_cache.go index 9b4360282b2ac..8e10d259b02c1 100644 --- a/pkg/statistics/handle/cache/stats_table_row_cache.go +++ b/pkg/statistics/handle/cache/stats_table_row_cache.go @@ -239,28 +239,27 @@ func getColLengthTables(sctx sessionctx.Context, tableIDs ...int64) (map[tableHi // GetDataAndIndexLength gets the data and index length of the table. func (c *StatsTableRowCache) GetDataAndIndexLength(info *model.TableInfo, physicalID int64, rowCount uint64) (dataLength, indexLength uint64) { - columnLength := make(map[string]uint64, len(info.Columns)) - for _, col := range info.Columns { + columnLength := make([]uint64, len(info.Columns)) + for i, col := range info.Columns { if col.State != model.StatePublic { continue } - length := col.FieldType.StorageLength() - if length != types.VarStorageLen { - columnLength[col.Name.L] = rowCount * uint64(length) + var length uint64 + if storageLen := col.FieldType.StorageLength(); storageLen != types.VarStorageLen { + length = rowCount * uint64(storageLen) } else { - length := c.GetColLength(tableHistID{tableID: physicalID, histID: col.ID}) - columnLength[col.Name.L] = length + length = c.GetColLength(tableHistID{tableID: physicalID, histID: col.ID}) } - } - for _, length := range columnLength { dataLength += length + columnLength[i] = length } + for _, idx := range info.Indices { if idx.State != model.StatePublic { continue } if info.GetPartitionInfo() != nil { - // Global indexes calcuated in table level. + // Global indexes calculated in table level. if idx.Global && info.ID != physicalID { continue } @@ -271,7 +270,7 @@ func (c *StatsTableRowCache) GetDataAndIndexLength(info *model.TableInfo, physic } for _, col := range idx.Columns { if col.Length == types.UnspecifiedLength { - indexLength += columnLength[col.Name.L] + indexLength += columnLength[col.Offset] } else { indexLength += rowCount * uint64(col.Length) } From 671d89f5c240f7421a7d944f1befc20bb3a96cd1 Mon Sep 17 00:00:00 2001 From: tangenta Date: Tue, 12 Nov 2024 12:13:31 +0800 Subject: [PATCH 4/5] fix TestInfoSchemaFieldValue --- pkg/infoschema/test/clustertablestest/tables_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/infoschema/test/clustertablestest/tables_test.go b/pkg/infoschema/test/clustertablestest/tables_test.go index bb2c20197784b..9c3b62d1e1223 100644 --- a/pkg/infoschema/test/clustertablestest/tables_test.go +++ b/pkg/infoschema/test/clustertablestest/tables_test.go @@ -93,7 +93,7 @@ func TestInfoSchemaFieldValue(t *testing.T) { tk.MustExec("drop table if exists t") tk.MustExec("create table t (c int auto_increment primary key, d int)") tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check( - testkit.Rows("1")) + testkit.Rows("0")) tk.MustExec("insert into t(c, d) values(1, 1)") tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check( testkit.Rows("2")) From bc5e3d1d4a5bca226ebb9d10e36593575c2a7f8b Mon Sep 17 00:00:00 2001 From: tangenta Date: Wed, 13 Nov 2024 11:30:42 +0800 Subject: [PATCH 5/5] address comment --- pkg/executor/infoschema_reader.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg/executor/infoschema_reader.go b/pkg/executor/infoschema_reader.go index d60e18d66b5b4..327e127006774 100644 --- a/pkg/executor/infoschema_reader.go +++ b/pkg/executor/infoschema_reader.go @@ -243,10 +243,7 @@ func getAutoIncrementID( tblInfo *model.TableInfo, ) int64 { if raw, ok := is.(*infoschema.SessionExtendedInfoSchema); ok { - v2, ok := raw.InfoSchema.(interface { - TableIsCached(id int64) bool - }) - if ok { + if ok, v2 := infoschema.IsV2(raw.InfoSchema); ok { isCached := v2.TableIsCached(tblInfo.ID) if !isCached { // Loading table info from kv storage invalidates the cached auto_increment id.