Skip to content

Commit ed6d669

Browse files
authored
infoschema: don't load table info to get auto_increment value (#57296) (#57494)
close #57295
1 parent 9df3763 commit ed6d669

File tree

6 files changed

+78
-14
lines changed

6 files changed

+78
-14
lines changed

pkg/executor/infoschema_reader.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,26 @@ func getAutoIncrementID(
242242
sctx sessionctx.Context,
243243
tblInfo *model.TableInfo,
244244
) int64 {
245+
if raw, ok := is.(*infoschema.SessionExtendedInfoSchema); ok {
246+
if ok, v2 := infoschema.IsV2(raw.InfoSchema); ok {
247+
isCached := v2.TableIsCached(tblInfo.ID)
248+
if !isCached {
249+
// Loading table info from kv storage invalidates the cached auto_increment id.
250+
return 0
251+
}
252+
}
253+
}
245254
tbl, ok := is.TableByID(context.Background(), tblInfo.ID)
246255
if !ok {
247256
return 0
248257
}
249-
return tbl.Allocators(sctx.GetTableCtx()).Get(autoid.AutoIncrementType).Base() + 1
258+
alloc := tbl.Allocators(sctx.GetTableCtx()).Get(autoid.AutoIncrementType)
259+
if alloc == nil || alloc.Base() == 0 {
260+
// It may not be loaded yet.
261+
// To show global next autoID, one should use `show table x next_row_id`.
262+
return 0
263+
}
264+
return alloc.Base() + 1
250265
}
251266

252267
func hasPriv(ctx sessionctx.Context, priv mysql.PrivilegeType) bool {

pkg/infoschema/infoschema_v2.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,31 @@ func (is *infoschemaV2) IterateAllTableItems(visit func(TableItem) bool) {
691691
})
692692
}
693693

694+
// TableIsCached checks whether the table is cached.
695+
func (is *infoschemaV2) TableIsCached(id int64) (ok bool) {
696+
if !tableIDIsValid(id) {
697+
return false
698+
}
699+
700+
itm, ok := is.searchTableItemByID(id)
701+
if !ok {
702+
return false
703+
}
704+
705+
if isTableVirtual(id) {
706+
if raw, exist := is.Data.specials.Load(itm.dbName.L); exist {
707+
schTbls := raw.(*schemaTables)
708+
_, ok = schTbls.tables[itm.tableName.L]
709+
return ok
710+
}
711+
return false
712+
}
713+
714+
key := tableCacheKey{itm.tableID, itm.schemaVersion}
715+
tbl, found := is.tableCache.Get(key)
716+
return found && tbl != nil
717+
}
718+
694719
// IsSpecialDB tells whether the database is a special database.
695720
func IsSpecialDB(dbName string) bool {
696721
return dbName == util.InformationSchemaName.L ||

pkg/infoschema/test/clustertablestest/tables_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func TestInfoSchemaFieldValue(t *testing.T) {
9393
tk.MustExec("drop table if exists t")
9494
tk.MustExec("create table t (c int auto_increment primary key, d int)")
9595
tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check(
96-
testkit.Rows("1"))
96+
testkit.Rows("0"))
9797
tk.MustExec("insert into t(c, d) values(1, 1)")
9898
tk.MustQuery("select auto_increment from information_schema.tables where table_name='t'").Check(
9999
testkit.Rows("2"))

pkg/infoschema/test/infoschemav2test/BUILD.bazel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ go_test(
88
"v2_test.go",
99
],
1010
flaky = True,
11-
shard_count = 11,
11+
shard_count = 12,
1212
deps = [
1313
"//pkg/domain",
1414
"//pkg/domain/infosync",
1515
"//pkg/infoschema",
1616
"//pkg/infoschema/context",
17+
"//pkg/meta/autoid",
1718
"//pkg/parser/auth",
1819
"//pkg/parser/model",
1920
"//pkg/sessionctx/variable",

pkg/infoschema/test/infoschemav2test/v2_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/pingcap/tidb/pkg/domain/infosync"
2929
"github.com/pingcap/tidb/pkg/infoschema"
3030
infoschemacontext "github.com/pingcap/tidb/pkg/infoschema/context"
31+
"github.com/pingcap/tidb/pkg/meta/autoid"
3132
"github.com/pingcap/tidb/pkg/parser/auth"
3233
"github.com/pingcap/tidb/pkg/parser/model"
3334
"github.com/pingcap/tidb/pkg/sessionctx/variable"
@@ -534,3 +535,26 @@ func TestSnapshotInfoschemaReader(t *testing.T) {
534535
sql = fmt.Sprintf("select * from INFORMATION_SCHEMA.TABLES as of timestamp '%s' where table_schema = 'issue55827'", timeStr)
535536
tk.MustQuery(sql).Check(testkit.Rows())
536537
}
538+
539+
func TestInfoSchemaCachedAutoIncrement(t *testing.T) {
540+
store := testkit.CreateMockStore(t)
541+
tk := testkit.NewTestKit(t, store)
542+
tk.MustExec("use test")
543+
autoid.SetStep(1)
544+
tk.MustExec("set @@global.tidb_schema_cache_size = 0;")
545+
tk.MustExec("create table t (a int primary key auto_increment);")
546+
autoIncQuery := "select auto_increment from information_schema.tables where table_name = 't' and table_schema = 'test';"
547+
548+
tk.MustQuery(autoIncQuery).Check(testkit.Rows("0"))
549+
tk.MustExec("insert into t values (),(),();")
550+
tk.MustQuery(autoIncQuery).Check(testkit.Rows("4"))
551+
552+
tk.MustExec("set @@global.tidb_schema_cache_size = 1024 * 1024 * 1024;")
553+
tk.MustExec("create table t1 (a int);") // trigger infoschema cache reload
554+
tk.MustQuery(autoIncQuery).Check(testkit.Rows("0"))
555+
tk.MustExec("insert into t values ();")
556+
tk.MustQuery(autoIncQuery).Check(testkit.Rows("5"))
557+
tk.MustExec("set @@global.tidb_schema_cache_size = 0;")
558+
tk.MustExec("drop table t1;") // trigger infoschema cache reload
559+
tk.MustQuery(autoIncQuery).Check(testkit.Rows("0"))
560+
}

pkg/statistics/handle/cache/stats_table_row_cache.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -239,28 +239,27 @@ func getColLengthTables(sctx sessionctx.Context, tableIDs ...int64) (map[tableHi
239239

240240
// GetDataAndIndexLength gets the data and index length of the table.
241241
func (c *StatsTableRowCache) GetDataAndIndexLength(info *model.TableInfo, physicalID int64, rowCount uint64) (dataLength, indexLength uint64) {
242-
columnLength := make(map[string]uint64, len(info.Columns))
243-
for _, col := range info.Columns {
242+
columnLength := make([]uint64, len(info.Columns))
243+
for i, col := range info.Columns {
244244
if col.State != model.StatePublic {
245245
continue
246246
}
247-
length := col.FieldType.StorageLength()
248-
if length != types.VarStorageLen {
249-
columnLength[col.Name.L] = rowCount * uint64(length)
247+
var length uint64
248+
if storageLen := col.FieldType.StorageLength(); storageLen != types.VarStorageLen {
249+
length = rowCount * uint64(storageLen)
250250
} else {
251-
length := c.GetColLength(tableHistID{tableID: physicalID, histID: col.ID})
252-
columnLength[col.Name.L] = length
251+
length = c.GetColLength(tableHistID{tableID: physicalID, histID: col.ID})
253252
}
254-
}
255-
for _, length := range columnLength {
256253
dataLength += length
254+
columnLength[i] = length
257255
}
256+
258257
for _, idx := range info.Indices {
259258
if idx.State != model.StatePublic {
260259
continue
261260
}
262261
if info.GetPartitionInfo() != nil {
263-
// Global indexes calcuated in table level.
262+
// Global indexes calculated in table level.
264263
if idx.Global && info.ID != physicalID {
265264
continue
266265
}
@@ -271,7 +270,7 @@ func (c *StatsTableRowCache) GetDataAndIndexLength(info *model.TableInfo, physic
271270
}
272271
for _, col := range idx.Columns {
273272
if col.Length == types.UnspecifiedLength {
274-
indexLength += columnLength[col.Name.L]
273+
indexLength += columnLength[col.Offset]
275274
} else {
276275
indexLength += rowCount * uint64(col.Length)
277276
}

0 commit comments

Comments
 (0)