Skip to content
Open
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
6 changes: 6 additions & 0 deletions tests/realtikvtest/statisticstest/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ go_test(
flaky = True,
race = "on",
deps = [
<<<<<<< HEAD
"//statistics/handle",
"//testkit",
=======
"//pkg/parser/model",
"//pkg/statistics/asyncload",
"//pkg/testkit",
>>>>>>> ba5c6a9bc6a (statistics: add a testcase for issue 54022 (#54137))
"//tests/realtikvtest",
"@com_github_stretchr_testify//require",
],
Expand Down
75 changes: 75 additions & 0 deletions tests/realtikvtest/statisticstest/statistics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,19 @@
package statisticstest

import (
"context"
"fmt"
"testing"
"time"

<<<<<<< HEAD
"github.com/pingcap/tidb/statistics/handle"
"github.com/pingcap/tidb/testkit"
=======
"github.com/pingcap/tidb/pkg/parser/model"
"github.com/pingcap/tidb/pkg/statistics/asyncload"
"github.com/pingcap/tidb/pkg/testkit"
>>>>>>> ba5c6a9bc6a (statistics: add a testcase for issue 54022 (#54137))
"github.com/pingcap/tidb/tests/realtikvtest"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -221,3 +229,70 @@ func checkFMSketch(tk *testkit.TestKit) {
tk.MustQuery(`SHOW STATS_HISTOGRAMS WHERE TABLE_NAME='employees' and partition_name="global" and column_name="id"`).CheckAt([]int{6}, [][]any{
{"14"}})
}

func TestNoNeedIndexStatsLoading(t *testing.T) {
store, dom := realtikvtest.CreateMockStoreAndDomainAndSetup(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test;")
tk.MustExec("drop table if exists t;")
// 1. Create a table and the statsHandle.Update(do.InfoSchema()) will load this table into the stats cache.
tk.MustExec("create table if not exists t(a int, b int, index ia(a));")
// 2. Drop the stats of the stats, it will clean up all system table records for this table.
tk.MustExec("drop stats t;")
// 3. Insert some data and wait for the modify_count and the count is not null in the mysql.stats_meta.
tk.MustExec("insert into t value(1,1), (2,2);")
h := dom.StatsHandle()
require.NoError(t, h.DumpStatsDeltaToKV(true))
require.NoError(t, h.Update(dom.InfoSchema()))
// 4. Try to select some data from this table by ID, it would trigger an async load.
tk.MustExec("set tidb_opt_objective='determinate';")
tk.MustQuery("select * from t where a = 1 and b = 1;").Check(testkit.Rows("1 1"))
table, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.NoError(t, err)
checkTableIDInItems(t, table.Meta().ID)
}

func checkTableIDInItems(t *testing.T, tableID int64) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()

ticker := time.NewTicker(2 * time.Millisecond)
defer ticker.Stop()

done := make(chan bool)

// First, confirm that the table ID is in the items.
items := asyncload.AsyncLoadHistogramNeededItems.AllItems()
for _, item := range items {
if item.TableID == tableID {
// Then, continuously check until it no longer exists or timeout.
go func() {
for {
select {
case <-ticker.C:
items := asyncload.AsyncLoadHistogramNeededItems.AllItems()
found := false
for _, item := range items {
if item.TableID == tableID {
found = true
}
}
if !found {
done <- true
}
case <-ctx.Done():
return
}
}
}()
break
}
}

select {
case <-done:
t.Log("Table ID has been removed from items")
case <-ctx.Done():
t.Fatal("Timeout: Table ID was not removed from items within the time limit")
}
}