From af4b5caf74df23c465ecfc00957039b598ea6d03 Mon Sep 17 00:00:00 2001 From: flaky-claw Date: Wed, 15 Apr 2026 21:12:53 +0000 Subject: [PATCH 1/2] fix: stabilize flaky issue #67461 --- pkg/util/workloadrepo/BUILD.bazel | 2 ++ pkg/util/workloadrepo/worker_test.go | 44 +++++++++++++++++++--------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/pkg/util/workloadrepo/BUILD.bazel b/pkg/util/workloadrepo/BUILD.bazel index 7702e8de2b2e1..29f6997e3c342 100644 --- a/pkg/util/workloadrepo/BUILD.bazel +++ b/pkg/util/workloadrepo/BUILD.bazel @@ -60,6 +60,8 @@ go_test( "//pkg/parser/ast", "//pkg/parser/auth", "//pkg/parser/mysql", + "//pkg/session", + "//pkg/session/sessionapi", "//pkg/sessionctx", "//pkg/sessionctx/variable", "//pkg/testkit", diff --git a/pkg/util/workloadrepo/worker_test.go b/pkg/util/workloadrepo/worker_test.go index d7b4219e679b1..fe9a81e815440 100644 --- a/pkg/util/workloadrepo/worker_test.go +++ b/pkg/util/workloadrepo/worker_test.go @@ -32,6 +32,8 @@ import ( "github.com/pingcap/tidb/pkg/parser/ast" "github.com/pingcap/tidb/pkg/parser/auth" "github.com/pingcap/tidb/pkg/parser/mysql" + "github.com/pingcap/tidb/pkg/session" + "github.com/pingcap/tidb/pkg/session/sessionapi" "github.com/pingcap/tidb/pkg/sessionctx" "github.com/pingcap/tidb/pkg/sessionctx/variable" "github.com/pingcap/tidb/pkg/testkit" @@ -146,6 +148,10 @@ func waitForTables(ctx context.Context, t *testing.T, wrk *worker, now time.Time }, time.Minute, time.Second) } +func anchorPartitionTestTime(now time.Time) time.Time { + return time.Date(now.Year(), now.Month(), now.Day(), 12, 0, 0, 0, now.Location()) +} + func TestRaceToCreateTablesWorker(t *testing.T) { ctx, store, dom, addr := setupDomainAndContext(t) @@ -641,11 +647,20 @@ func createTableWithParts(ctx context.Context, t *testing.T, tk *testkit.TestKit require.True(t, validatePartitionsMatchExpected(ctx, t, sess, tbl, partitions)) } +func createTableWithPartsForSession(ctx context.Context, t *testing.T, se sessionapi.Session, tbl *repositoryTable, + sess sessionctx.Context, partitions []time.Time) { + createSQL, err := buildCreateQuery(ctx, sess, tbl) + require.NoError(t, err) + createSQL += buildPartitionString(partitions) + session.MustExec(t, se, createSQL) + require.True(t, validatePartitionsMatchExpected(ctx, t, sess, tbl, partitions)) +} + func validatePartitionCreation(ctx context.Context, now time.Time, t *testing.T, - sess sessionctx.Context, tk *testkit.TestKit, wrk *worker, + sess sessionctx.Context, se sessionapi.Session, wrk *worker, firstTestFails bool, tableName string, partitions []time.Time, expectedParts []time.Time) { tbl := getTable(t, tableName, wrk) - createTableWithParts(ctx, t, tk, tbl, sess, partitions) + createTableWithPartsForSession(ctx, t, se, tbl, sess, partitions) is := sess.GetLatestInfoSchema().(infoschema.InfoSchema) require.False(t, firstTestFails == checkTableExistsByIS(ctx, is, tbl.destTable, now)) @@ -662,56 +677,57 @@ func validatePartitionCreation(ctx context.Context, now time.Time, t *testing.T, func TestCreatePartition(t *testing.T) { ctx, store, dom, addr := setupDomainAndContext(t) wrk := setupWorker(ctx, t, addr, dom, "worker", true) - tk := testkit.NewTestKit(t, store) + se, err := session.CreateSession4Test(store) + require.NoError(t, err) + t.Cleanup(se.Close) - tk.MustExec("create database WORKLOAD_SCHEMA") - tk.MustExec("use WORKLOAD_SCHEMA") + session.MustExec(t, se, "create database WORKLOAD_SCHEMA") + session.MustExec(t, se, "use WORKLOAD_SCHEMA") _sessctx := wrk.getSessionWithRetry() sess := _sessctx.(sessionctx.Context) wrk.fillInTableNames() - now := time.Now() + now := anchorPartitionTestTime(time.Now()) /* Tables without partitions are not currently supported. */ // Should create one partition for today and tomorrow on a table with only old partitions before today. partitions := []time.Time{now.AddDate(0, 0, -1)} expectedParts := []time.Time{now.AddDate(0, 0, -1), now, now.AddDate(0, 0, 1)} - validatePartitionCreation(ctx, now, t, sess, tk, wrk, true, "PROCESSLIST", partitions, expectedParts) + validatePartitionCreation(ctx, now, t, sess, se, wrk, true, "PROCESSLIST", partitions, expectedParts) // Should create one partition for tomorrow on a table with only a partition for today. partitions = []time.Time{now} expectedParts = []time.Time{now, now.AddDate(0, 0, 1)} - validatePartitionCreation(ctx, now, t, sess, tk, wrk, true, "DATA_LOCK_WAITS", partitions, expectedParts) + validatePartitionCreation(ctx, now, t, sess, se, wrk, true, "DATA_LOCK_WAITS", partitions, expectedParts) // Should not create any partitions on a table with only a partition for tomorrow. partitions = []time.Time{now.AddDate(0, 0, 1)} expectedParts = []time.Time{now.AddDate(0, 0, 1)} - validatePartitionCreation(ctx, now, t, sess, tk, wrk, false, "TIDB_TRX", partitions, expectedParts) + validatePartitionCreation(ctx, now, t, sess, se, wrk, false, "TIDB_TRX", partitions, expectedParts) // Should not create any partitions on a table with only partitions for both today and tomorrow. partitions = []time.Time{now, now.AddDate(0, 0, 1)} expectedParts = []time.Time{now, now.AddDate(0, 0, 1)} - validatePartitionCreation(ctx, now, t, sess, tk, wrk, false, "MEMORY_USAGE", partitions, expectedParts) + validatePartitionCreation(ctx, now, t, sess, se, wrk, false, "MEMORY_USAGE", partitions, expectedParts) // Should not create any partitions on a table with a partition for the day after tomorrow. partitions = []time.Time{now.AddDate(0, 0, 2)} expectedParts = []time.Time{now.AddDate(0, 0, 2)} - validatePartitionCreation(ctx, now, t, sess, tk, wrk, false, "DEADLOCKS", partitions, expectedParts) + validatePartitionCreation(ctx, now, t, sess, se, wrk, false, "DEADLOCKS", partitions, expectedParts) // Should not fill in missing partitions on a table with a partition for dates beyond tomorrow. partitions = []time.Time{now, now.AddDate(0, 0, 3)} expectedParts = []time.Time{now, now.AddDate(0, 0, 3)} - validatePartitionCreation(ctx, now, t, sess, tk, wrk, false, "TIDB_INDEX_USAGE", partitions, expectedParts) + validatePartitionCreation(ctx, now, t, sess, se, wrk, false, "TIDB_INDEX_USAGE", partitions, expectedParts) // this table should be updated when the repository is enabled partitions = []time.Time{now} - createTableWithParts(ctx, t, tk, getTable(t, "TIDB_STATEMENTS_STATS", wrk), sess, partitions) + createTableWithPartsForSession(ctx, t, se, getTable(t, "TIDB_STATEMENTS_STATS", wrk), sess, partitions) // turn on the repository and see if it creates the remaining tables - now = time.Now() wrk.setRepositoryDest(ctx, "table") waitForTables(ctx, t, wrk, now) } From 4310e3e018cbe5c6bf744c6e99b3ff68899dd0b1 Mon Sep 17 00:00:00 2001 From: yinsustart Date: Sat, 9 May 2026 12:10:48 +0800 Subject: [PATCH 2/2] pkg/util/workloadrepo: address review comments --- pkg/util/workloadrepo/worker_test.go | 30 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/pkg/util/workloadrepo/worker_test.go b/pkg/util/workloadrepo/worker_test.go index fe9a81e815440..a586abbf133bb 100644 --- a/pkg/util/workloadrepo/worker_test.go +++ b/pkg/util/workloadrepo/worker_test.go @@ -148,10 +148,6 @@ func waitForTables(ctx context.Context, t *testing.T, wrk *worker, now time.Time }, time.Minute, time.Second) } -func anchorPartitionTestTime(now time.Time) time.Time { - return time.Date(now.Year(), now.Month(), now.Day(), 12, 0, 0, 0, now.Location()) -} - func TestRaceToCreateTablesWorker(t *testing.T) { ctx, store, dom, addr := setupDomainAndContext(t) @@ -638,22 +634,27 @@ func buildPartitionString(partitions []time.Time) string { return sb.String() } -func createTableWithParts(ctx context.Context, t *testing.T, tk *testkit.TestKit, tbl *repositoryTable, - sess sessionctx.Context, partitions []time.Time) { +func createTableWithPartsByExec(ctx context.Context, t *testing.T, tbl *repositoryTable, + sess sessionctx.Context, partitions []time.Time, exec func(string)) { createSQL, err := buildCreateQuery(ctx, sess, tbl) require.NoError(t, err) createSQL += buildPartitionString(partitions) - tk.MustExec(createSQL) + exec(createSQL) require.True(t, validatePartitionsMatchExpected(ctx, t, sess, tbl, partitions)) } +func createTableWithParts(ctx context.Context, t *testing.T, tk *testkit.TestKit, tbl *repositoryTable, + sess sessionctx.Context, partitions []time.Time) { + createTableWithPartsByExec(ctx, t, tbl, sess, partitions, func(createSQL string) { + tk.MustExec(createSQL) + }) +} + func createTableWithPartsForSession(ctx context.Context, t *testing.T, se sessionapi.Session, tbl *repositoryTable, sess sessionctx.Context, partitions []time.Time) { - createSQL, err := buildCreateQuery(ctx, sess, tbl) - require.NoError(t, err) - createSQL += buildPartitionString(partitions) - session.MustExec(t, se, createSQL) - require.True(t, validatePartitionsMatchExpected(ctx, t, sess, tbl, partitions)) + createTableWithPartsByExec(ctx, t, tbl, sess, partitions, func(createSQL string) { + session.MustExec(t, se, createSQL) + }) } func validatePartitionCreation(ctx context.Context, now time.Time, t *testing.T, @@ -689,7 +690,10 @@ func TestCreatePartition(t *testing.T) { wrk.fillInTableNames() - now := anchorPartitionTestTime(time.Now()) + now := time.Now() + // The test builds date-based partitions with AddDate and TO_DAYS, so anchor at noon to avoid + // instability around wall-clock day boundaries. + now = time.Date(now.Year(), now.Month(), now.Day(), 12, 0, 0, 0, now.Location()) /* Tables without partitions are not currently supported. */