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

infoschema: fix snapshot read bug for information_schema.tables #55830

Merged
merged 3 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions pkg/infoschema/infoschema_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -653,19 +653,23 @@ type TableItem struct {

// IterateAllTableItems is used for special performance optimization.
// Used by executor/infoschema_reader.go to handle reading from INFORMATION_SCHEMA.TABLES.
// If visit return false, stop the iterate process.
func (is *infoschemaV2) IterateAllTableItems(visit func(TableItem) bool) {
pivot, ok := is.byName.Max()
max, ok := is.byName.Max()
if !ok {
return
}
if !visit(TableItem{DBName: pivot.dbName, TableName: pivot.tableName}) {
return
}
is.byName.Descend(pivot, func(item tableItem) bool {
if pivot.dbName == item.dbName && pivot.tableName == item.tableName {
return true // skip MVCC version
var pivot *tableItem
is.byName.Descend(max, func(item tableItem) bool {
if item.schemaVersion > is.schemaMetaVersion {
// skip MVCC version, those items are not visible to the queried schema version
return true
}
pivot = item
if pivot != nil && pivot.dbName == item.dbName && pivot.tableName == item.tableName {
// skip MVCC version, this db.table has been visited already
return true
}
pivot = &item
if !item.tomb {
return visit(TableItem{DBName: item.dbName, TableName: item.tableName})
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/infoschema/test/infoschemav2test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ go_test(
"v2_test.go",
],
flaky = True,
shard_count = 10,
shard_count = 11,
deps = [
"//pkg/domain",
"//pkg/domain/infosync",
Expand Down
29 changes: 29 additions & 0 deletions pkg/infoschema/test/infoschemav2test/v2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,32 @@ func TestSchemaSimpleTableInfos(t *testing.T) {
require.Equal(t, tblInfos[0].Name.L, "t2")
require.Equal(t, tblInfos[1].Name.L, "t1")
}

func TestSnapshotInfoschemaReader(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
// For mocktikv, safe point is not initialized, we manually insert it for snapshot to use.
safePointName := "tikv_gc_safe_point"
safePointValue := "20160102-15:04:05 -0700"
safePointComment := "All versions after safe point can be accessed. (DO NOT EDIT)"
updateSafePoint := fmt.Sprintf(`INSERT INTO mysql.tidb VALUES ('%[1]s', '%[2]s', '%[3]s')
ON DUPLICATE KEY
UPDATE variable_value = '%[2]s', comment = '%[3]s'`, safePointName, safePointValue, safePointComment)
tk.MustExec(updateSafePoint)

tk.MustExec("create database issue55827")
tk.MustExec("use issue55827")

time1 := time.Now()
timeStr := time1.Format("2006-1-2 15:04:05.000")

tk.MustExec("create table t (id int primary key);")
tk.MustQuery("select count(*) from INFORMATION_SCHEMA.TABLES where table_schema = 'issue55827'").Check(testkit.Rows("1"))
tk.MustQuery("select count(tidb_table_id) from INFORMATION_SCHEMA.TABLES where table_schema = 'issue55827'").Check(testkit.Rows("1"))

// For issue 55827
sql := fmt.Sprintf("select count(*) from INFORMATION_SCHEMA.TABLES as of timestamp '%s' where table_schema = 'issue55827'", timeStr)
tk.MustQuery(sql).Check(testkit.Rows("0"))
sql = fmt.Sprintf("select * from INFORMATION_SCHEMA.TABLES as of timestamp '%s' where table_schema = 'issue55827'", timeStr)
tk.MustQuery(sql).Check(testkit.Rows())
}