From dc6258ab99f2763f28d81201e7559db1a5fce20d Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Fri, 6 Dec 2024 17:40:44 +0800 Subject: [PATCH 1/4] This is an automated cherry-pick of #58048 Signed-off-by: ti-chi-bot --- pkg/statistics/handle/handletest/BUILD.bazel | 2 +- .../handle/handletest/handle_test.go | 28 +++++++++++++++++++ pkg/statistics/handle/storage/read.go | 5 +++- pkg/statistics/handle/util/BUILD.bazel | 4 +++ pkg/statistics/handle/util/util.go | 18 ++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/pkg/statistics/handle/handletest/BUILD.bazel b/pkg/statistics/handle/handletest/BUILD.bazel index 505a2c5737c70..81a73e7f19ef3 100644 --- a/pkg/statistics/handle/handletest/BUILD.bazel +++ b/pkg/statistics/handle/handletest/BUILD.bazel @@ -9,7 +9,7 @@ go_test( ], flaky = True, race = "on", - shard_count = 33, + shard_count = 34, deps = [ "//pkg/config", "//pkg/domain", diff --git a/pkg/statistics/handle/handletest/handle_test.go b/pkg/statistics/handle/handletest/handle_test.go index ce1b8d2d1f97b..64419c6880ff4 100644 --- a/pkg/statistics/handle/handletest/handle_test.go +++ b/pkg/statistics/handle/handletest/handle_test.go @@ -1462,3 +1462,31 @@ func TestSkipMissingPartitionStats(t *testing.T) { require.True(t, idx.IsStatsInitialized()) } } + +func TestStatsCacheUpdateTimeout(t *testing.T) { + store, dom := testkit.CreateMockStoreAndDomain(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set @@tidb_partition_prune_mode = 'dynamic'") + tk.MustExec("set @@tidb_skip_missing_partition_stats = 1") + tk.MustExec("create table t (a int, b int, c int, index idx_b(b)) partition by range (a) (partition p0 values less than (100), partition p1 values less than (200), partition p2 values less than (300))") + tk.MustExec("insert into t values (1,1,1), (2,2,2), (101,101,101), (102,102,102), (201,201,201), (202,202,202)") + analyzehelper.TriggerPredicateColumnsCollection(t, tk, store, "t", "a", "b", "c") + h := dom.StatsHandle() + require.NoError(t, h.DumpStatsDeltaToKV(true)) + tk.MustExec("analyze table t partition p0, p1") + tbl, err := dom.InfoSchema().TableByName(context.Background(), model.NewCIStr("test"), model.NewCIStr("t")) + require.NoError(t, err) + tblInfo := tbl.Meta() + globalStats := h.GetTableStats(tblInfo) + require.Equal(t, 6, int(globalStats.RealtimeCount)) + require.Equal(t, 2, int(globalStats.ModifyCount)) + require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/statistics/handle/util/ExecRowsTimeout", "return()")) + defer func() { + require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/statistics/handle/util/ExecRowsTimeout")) + }() + require.Error(t, h.Update(context.Background(), dom.InfoSchema())) + globalStats2 := h.GetTableStats(tblInfo) + require.Equal(t, 6, int(globalStats2.RealtimeCount)) + require.Equal(t, 2, int(globalStats2.ModifyCount)) +} diff --git a/pkg/statistics/handle/storage/read.go b/pkg/statistics/handle/storage/read.go index 1a9feec3ff732..63b34737b4b20 100644 --- a/pkg/statistics/handle/storage/read.go +++ b/pkg/statistics/handle/storage/read.go @@ -529,8 +529,11 @@ func TableStatsFromStorage(sctx sessionctx.Context, snapshot uint64, tableInfo * table.RealtimeCount = realtimeCount rows, _, err := util.ExecRows(sctx, "select table_id, is_index, hist_id, distinct_count, version, null_count, tot_col_size, stats_ver, flag, correlation, last_analyze_pos from mysql.stats_histograms where table_id = %?", tableID) + if err != nil { + return nil, err + } // Check deleted table. - if err != nil || len(rows) == 0 { + if len(rows) == 0 { return nil, nil } for _, row := range rows { diff --git a/pkg/statistics/handle/util/BUILD.bazel b/pkg/statistics/handle/util/BUILD.bazel index 51be207e062e5..6e738449f5447 100644 --- a/pkg/statistics/handle/util/BUILD.bazel +++ b/pkg/statistics/handle/util/BUILD.bazel @@ -29,7 +29,11 @@ go_library( "//pkg/util/sqlexec/mock", "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", +<<<<<<< HEAD "@com_github_pingcap_tipb//go-tipb", +======= + "@com_github_pingcap_failpoint//:failpoint", +>>>>>>> 1521bf723dd (statistics: right deal with error for reading stats from storage (#58048)) "@com_github_tiancaiamao_gp//:gp", "@com_github_tikv_client_go_v2//oracle", "@org_uber_go_atomic//:atomic", diff --git a/pkg/statistics/handle/util/util.go b/pkg/statistics/handle/util/util.go index 1db8addc5fae3..5ca6b5ea2e1bd 100644 --- a/pkg/statistics/handle/util/util.go +++ b/pkg/statistics/handle/util/util.go @@ -20,6 +20,7 @@ import ( "time" "github.com/pingcap/errors" + "github.com/pingcap/failpoint" "github.com/pingcap/tidb/pkg/kv" "github.com/pingcap/tidb/pkg/parser/ast" "github.com/pingcap/tidb/pkg/parser/terror" @@ -219,7 +220,24 @@ func Exec(sctx sessionctx.Context, sql string, args ...any) (sqlexec.RecordSet, } // ExecRows is a helper function to execute sql and return rows and fields. +<<<<<<< HEAD func ExecRows(sctx sessionctx.Context, sql string, args ...any) (rows []chunk.Row, fields []*ast.ResultField, err error) { +======= +func ExecRows(sctx sessionctx.Context, sql string, args ...any) (rows []chunk.Row, fields []*resolve.ResultField, err error) { + failpoint.Inject("ExecRowsTimeout", func() { + failpoint.Return(nil, nil, errors.New("inject timeout error")) + }) + return ExecRowsWithCtx(StatsCtx, sctx, sql, args...) +} + +// ExecRowsWithCtx is a helper function to execute sql and return rows and fields. +func ExecRowsWithCtx( + ctx context.Context, + sctx sessionctx.Context, + sql string, + args ...any, +) (rows []chunk.Row, fields []*resolve.ResultField, err error) { +>>>>>>> 1521bf723dd (statistics: right deal with error for reading stats from storage (#58048)) if intest.InTest { if v := sctx.Value(mock.RestrictedSQLExecutorKey{}); v != nil { return v.(*mock.MockRestrictedSQLExecutor).ExecRestrictedSQL(StatsCtx, From c851d79f9da5658c1c41c39a985fb4a87a10a14e Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Mon, 9 Dec 2024 13:49:09 +0800 Subject: [PATCH 2/4] statistics: trigger --- pkg/statistics/handle/util/BUILD.bazel | 3 --- pkg/statistics/handle/util/util.go | 14 -------------- 2 files changed, 17 deletions(-) diff --git a/pkg/statistics/handle/util/BUILD.bazel b/pkg/statistics/handle/util/BUILD.bazel index 6e738449f5447..ecb35d2b9148c 100644 --- a/pkg/statistics/handle/util/BUILD.bazel +++ b/pkg/statistics/handle/util/BUILD.bazel @@ -29,11 +29,8 @@ go_library( "//pkg/util/sqlexec/mock", "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", -<<<<<<< HEAD "@com_github_pingcap_tipb//go-tipb", -======= "@com_github_pingcap_failpoint//:failpoint", ->>>>>>> 1521bf723dd (statistics: right deal with error for reading stats from storage (#58048)) "@com_github_tiancaiamao_gp//:gp", "@com_github_tikv_client_go_v2//oracle", "@org_uber_go_atomic//:atomic", diff --git a/pkg/statistics/handle/util/util.go b/pkg/statistics/handle/util/util.go index 5ca6b5ea2e1bd..c546b410623e0 100644 --- a/pkg/statistics/handle/util/util.go +++ b/pkg/statistics/handle/util/util.go @@ -220,24 +220,10 @@ func Exec(sctx sessionctx.Context, sql string, args ...any) (sqlexec.RecordSet, } // ExecRows is a helper function to execute sql and return rows and fields. -<<<<<<< HEAD func ExecRows(sctx sessionctx.Context, sql string, args ...any) (rows []chunk.Row, fields []*ast.ResultField, err error) { -======= -func ExecRows(sctx sessionctx.Context, sql string, args ...any) (rows []chunk.Row, fields []*resolve.ResultField, err error) { failpoint.Inject("ExecRowsTimeout", func() { failpoint.Return(nil, nil, errors.New("inject timeout error")) }) - return ExecRowsWithCtx(StatsCtx, sctx, sql, args...) -} - -// ExecRowsWithCtx is a helper function to execute sql and return rows and fields. -func ExecRowsWithCtx( - ctx context.Context, - sctx sessionctx.Context, - sql string, - args ...any, -) (rows []chunk.Row, fields []*resolve.ResultField, err error) { ->>>>>>> 1521bf723dd (statistics: right deal with error for reading stats from storage (#58048)) if intest.InTest { if v := sctx.Value(mock.RestrictedSQLExecutorKey{}); v != nil { return v.(*mock.MockRestrictedSQLExecutor).ExecRestrictedSQL(StatsCtx, From 178622d0aee1d0812000abc0b4d6e11e4e47a944 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Mon, 9 Dec 2024 13:54:07 +0800 Subject: [PATCH 3/4] statistics: trigger --- pkg/statistics/handle/util/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/statistics/handle/util/BUILD.bazel b/pkg/statistics/handle/util/BUILD.bazel index ecb35d2b9148c..b41c62030485e 100644 --- a/pkg/statistics/handle/util/BUILD.bazel +++ b/pkg/statistics/handle/util/BUILD.bazel @@ -29,8 +29,8 @@ go_library( "//pkg/util/sqlexec/mock", "@com_github_ngaut_pools//:pools", "@com_github_pingcap_errors//:errors", - "@com_github_pingcap_tipb//go-tipb", "@com_github_pingcap_failpoint//:failpoint", + "@com_github_pingcap_tipb//go-tipb", "@com_github_tiancaiamao_gp//:gp", "@com_github_tikv_client_go_v2//oracle", "@org_uber_go_atomic//:atomic", From 60b395939f243fa120dfa8d1442cb5f4113193b0 Mon Sep 17 00:00:00 2001 From: Weizhen Wang Date: Mon, 9 Dec 2024 14:31:02 +0800 Subject: [PATCH 4/4] statistics: trigger --- pkg/statistics/handle/handletest/handle_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/statistics/handle/handletest/handle_test.go b/pkg/statistics/handle/handletest/handle_test.go index 64419c6880ff4..93453f903e1d2 100644 --- a/pkg/statistics/handle/handletest/handle_test.go +++ b/pkg/statistics/handle/handletest/handle_test.go @@ -1471,11 +1471,10 @@ func TestStatsCacheUpdateTimeout(t *testing.T) { tk.MustExec("set @@tidb_skip_missing_partition_stats = 1") tk.MustExec("create table t (a int, b int, c int, index idx_b(b)) partition by range (a) (partition p0 values less than (100), partition p1 values less than (200), partition p2 values less than (300))") tk.MustExec("insert into t values (1,1,1), (2,2,2), (101,101,101), (102,102,102), (201,201,201), (202,202,202)") - analyzehelper.TriggerPredicateColumnsCollection(t, tk, store, "t", "a", "b", "c") h := dom.StatsHandle() require.NoError(t, h.DumpStatsDeltaToKV(true)) tk.MustExec("analyze table t partition p0, p1") - tbl, err := dom.InfoSchema().TableByName(context.Background(), model.NewCIStr("test"), model.NewCIStr("t")) + tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t")) require.NoError(t, err) tblInfo := tbl.Meta() globalStats := h.GetTableStats(tblInfo) @@ -1485,7 +1484,7 @@ func TestStatsCacheUpdateTimeout(t *testing.T) { defer func() { require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/statistics/handle/util/ExecRowsTimeout")) }() - require.Error(t, h.Update(context.Background(), dom.InfoSchema())) + require.Error(t, h.Update(dom.InfoSchema())) globalStats2 := h.GetTableStats(tblInfo) require.Equal(t, 6, int(globalStats2.RealtimeCount)) require.Equal(t, 2, int(globalStats2.ModifyCount))