From ac00309ba62cd5918b97c4d656cfa9ba4cb7c973 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Fri, 13 Sep 2024 09:25:17 +0800 Subject: [PATCH 1/4] statistics: add into write to avoid inaccurate results Signed-off-by: Weizhen Wang --- pkg/statistics/handle/storage/read.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pkg/statistics/handle/storage/read.go b/pkg/statistics/handle/storage/read.go index e101e85e3f03e..d639467cd9b5a 100644 --- a/pkg/statistics/handle/storage/read.go +++ b/pkg/statistics/handle/storage/read.go @@ -43,7 +43,20 @@ import ( // StatsMetaCountAndModifyCount reads count and modify_count for the given table from mysql.stats_meta. func StatsMetaCountAndModifyCount(sctx sessionctx.Context, tableID int64) (count, modifyCount int64, isNull bool, err error) { - rows, _, err := util.ExecRows(sctx, "select count, modify_count from mysql.stats_meta where table_id = %?", tableID) + return statsMetaCountAndModifyCount(sctx, tableID, false) +} + +// StatsMetaCountAndModifyCountForUpdate reads count and modify_count for the given table from mysql.stats_meta with lock. +func StatsMetaCountAndModifyCountForUpdate(sctx sessionctx.Context, tableID int64) (count, modifyCount int64, isNull bool, err error) { + return statsMetaCountAndModifyCount(sctx, tableID, false) +} + +func statsMetaCountAndModifyCount(sctx sessionctx.Context, tableID int64, forUpdate bool) (count, modifyCount int64, isNull bool, err error) { + sql := "select count, modify_count from mysql.stats_meta where table_id = %?" + if forUpdate { + sql += " for update" + } + rows, _, err := util.ExecRows(sctx, sql, tableID) if err != nil { return 0, 0, false, err } From 09493a268cd2e43c0126dabbb16fd64f369b56c9 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Sat, 14 Sep 2024 00:08:25 +0800 Subject: [PATCH 2/4] update Signed-off-by: Weizhen Wang --- pkg/statistics/handle/ddl/BUILD.bazel | 5 ++++- pkg/statistics/handle/ddl/ddl.go | 9 +++++++++ pkg/statistics/handle/ddl/ddl_test.go | 29 +++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/pkg/statistics/handle/ddl/BUILD.bazel b/pkg/statistics/handle/ddl/BUILD.bazel index ca5ca9bdc5fad..268b15ea3e435 100644 --- a/pkg/statistics/handle/ddl/BUILD.bazel +++ b/pkg/statistics/handle/ddl/BUILD.bazel @@ -33,14 +33,17 @@ go_test( timeout = "short", srcs = ["ddl_test.go"], flaky = True, - shard_count = 18, + shard_count = 19, deps = [ + ":ddl", "//pkg/ddl/notifier", "//pkg/meta/model", "//pkg/parser/model", "//pkg/planner/cardinality", + "//pkg/statistics/handle/storage", "//pkg/testkit", "//pkg/types", + "//pkg/util", "//pkg/util/mock", "@com_github_stretchr_testify//require", ], diff --git a/pkg/statistics/handle/ddl/ddl.go b/pkg/statistics/handle/ddl/ddl.go index d7c35e6dd132d..685ec8e65a931 100644 --- a/pkg/statistics/handle/ddl/ddl.go +++ b/pkg/statistics/handle/ddl/ddl.go @@ -186,6 +186,15 @@ func (h *ddlHandlerImpl) HandleDDLEvent(s *notifier.SchemaChangeEvent) error { return nil } +// UpdateStatsWithCountDeltaAndModifyCountDeltaForTest updates the global stats with the given count delta and modify count delta. +func UpdateStatsWithCountDeltaAndModifyCountDeltaForTest( + sctx sessionctx.Context, + tableID int64, + countDelta, modifyCountDelta int64, +) error { + return updateStatsWithCountDeltaAndModifyCountDelta(sctx, tableID, countDelta, modifyCountDelta) +} + // updateStatsWithCountDeltaAndModifyCountDelta updates // the global stats with the given count delta and modify count delta. // Only used by some special DDLs, such as exchange partition. diff --git a/pkg/statistics/handle/ddl/ddl_test.go b/pkg/statistics/handle/ddl/ddl_test.go index 5eebb86d33168..135d19637a834 100644 --- a/pkg/statistics/handle/ddl/ddl_test.go +++ b/pkg/statistics/handle/ddl/ddl_test.go @@ -23,8 +23,11 @@ import ( "github.com/pingcap/tidb/pkg/meta/model" pmodel "github.com/pingcap/tidb/pkg/parser/model" "github.com/pingcap/tidb/pkg/planner/cardinality" + "github.com/pingcap/tidb/pkg/statistics/handle/ddl" + "github.com/pingcap/tidb/pkg/statistics/handle/storage" "github.com/pingcap/tidb/pkg/testkit" "github.com/pingcap/tidb/pkg/types" + "github.com/pingcap/tidb/pkg/util" "github.com/pingcap/tidb/pkg/util/mock" "github.com/stretchr/testify/require" ) @@ -1311,3 +1314,29 @@ func findEvent(eventCh <-chan *notifier.SchemaChangeEvent, eventType model.Actio } } } + +func TestExchangePartition(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + + tk.MustExec("use test") + tk.MustExec("create table t (c1 int)") + is := dom.InfoSchema() + tbl, err := is.TableByName(context.Background(), pmodel.NewCIStr("test"), pmodel.NewCIStr("t")) + require.NoError(t, err) + var wg util.WaitGroupWrapper + for i := 0; i < 20; i++ { + tk1 := testkit.NewTestKit(t, store) + wg.Run(func() { + tk1.MustExec("begin") + ddl.UpdateStatsWithCountDeltaAndModifyCountDeltaForTest(tk1.Session(), tbl.Meta().ID, 10, 10) + tk1.MustExec("commit") + }) + } + wg.Wait() + count, modifyCount, isNull, err := storage.StatsMetaCountAndModifyCount(tk.Session(), tbl.Meta().ID) + require.NoError(t, err) + require.False(t, isNull) + require.Equal(t, int64(200), count) + require.Equal(t, int64(200), modifyCount) +} From 084033d81678b3fbad75aa43df0d1fac19cd2c5b Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Sat, 14 Sep 2024 00:49:57 +0800 Subject: [PATCH 3/4] update Signed-off-by: Weizhen Wang --- pkg/statistics/handle/ddl/ddl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/statistics/handle/ddl/ddl.go b/pkg/statistics/handle/ddl/ddl.go index 685ec8e65a931..bbe5e0868a097 100644 --- a/pkg/statistics/handle/ddl/ddl.go +++ b/pkg/statistics/handle/ddl/ddl.go @@ -235,7 +235,7 @@ func updateStatsWithCountDeltaAndModifyCountDelta( } // Because count can not be negative, so we need to get the current and calculate the delta. - count, modifyCount, isNull, err := storage.StatsMetaCountAndModifyCount(sctx, tableID) + count, modifyCount, isNull, err := storage.StatsMetaCountAndModifyCountForUpdate(sctx, tableID) if err != nil { return err } From a35ac9d0f56910efe904315a64113193ec4daa93 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Sat, 14 Sep 2024 01:06:00 +0800 Subject: [PATCH 4/4] Update pkg/statistics/handle/storage/read.go Co-authored-by: you06 --- pkg/statistics/handle/storage/read.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/statistics/handle/storage/read.go b/pkg/statistics/handle/storage/read.go index d639467cd9b5a..456e8154d64ec 100644 --- a/pkg/statistics/handle/storage/read.go +++ b/pkg/statistics/handle/storage/read.go @@ -48,7 +48,7 @@ func StatsMetaCountAndModifyCount(sctx sessionctx.Context, tableID int64) (count // StatsMetaCountAndModifyCountForUpdate reads count and modify_count for the given table from mysql.stats_meta with lock. func StatsMetaCountAndModifyCountForUpdate(sctx sessionctx.Context, tableID int64) (count, modifyCount int64, isNull bool, err error) { - return statsMetaCountAndModifyCount(sctx, tableID, false) + return statsMetaCountAndModifyCount(sctx, tableID, true) } func statsMetaCountAndModifyCount(sctx sessionctx.Context, tableID int64, forUpdate bool) (count, modifyCount int64, isNull bool, err error) {