Skip to content

Commit

Permalink
statistics: only query locks once (#49473)
Browse files Browse the repository at this point in the history
close #49472
  • Loading branch information
hi-rustin committed Dec 18, 2023
1 parent fb9d220 commit 23953a7
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 28 deletions.
4 changes: 2 additions & 2 deletions pkg/statistics/handle/autoanalyze/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ go_library(
"//pkg/sessionctx",
"//pkg/sessionctx/variable",
"//pkg/statistics",
"//pkg/statistics/handle/lockstats",
"//pkg/statistics/handle/logutil",
"//pkg/statistics/handle/types",
"//pkg/statistics/handle/util",
"//pkg/table",
"//pkg/types",
"//pkg/util",
"//pkg/util/chunk",
Expand All @@ -36,7 +36,7 @@ go_test(
timeout = "short",
srcs = ["autoanalyze_test.go"],
flaky = True,
shard_count = 9,
shard_count = 10,
deps = [
":autoanalyze",
"//pkg/domain/infosync",
Expand Down
38 changes: 12 additions & 26 deletions pkg/statistics/handle/autoanalyze/autoanalyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ import (
"github.com/pingcap/tidb/pkg/sessionctx"
"github.com/pingcap/tidb/pkg/sessionctx/variable"
"github.com/pingcap/tidb/pkg/statistics"
"github.com/pingcap/tidb/pkg/statistics/handle/lockstats"
statslogutil "github.com/pingcap/tidb/pkg/statistics/handle/logutil"
statstypes "github.com/pingcap/tidb/pkg/statistics/handle/types"
statsutil "github.com/pingcap/tidb/pkg/statistics/handle/util"
"github.com/pingcap/tidb/pkg/table"
"github.com/pingcap/tidb/pkg/types"
"github.com/pingcap/tidb/pkg/util"
"github.com/pingcap/tidb/pkg/util/chunk"
Expand Down Expand Up @@ -299,21 +299,6 @@ func getAutoAnalyzeParameters(sctx sessionctx.Context) map[string]string {
return parameters
}

func getAllTidsAndPids(tbls []table.Table) []int64 {
tidsAndPids := make([]int64, 0, len(tbls))
for _, tbl := range tbls {
tidsAndPids = append(tidsAndPids, tbl.Meta().ID)
tblInfo := tbl.Meta()
pi := tblInfo.GetPartitionInfo()
if pi != nil {
for _, def := range pi.Definitions {
tidsAndPids = append(tidsAndPids, def.ID)
}
}
}
return tidsAndPids
}

// HandleAutoAnalyze analyzes the newly created table or index.
func HandleAutoAnalyze(
sctx sessionctx.Context,
Expand Down Expand Up @@ -379,6 +364,17 @@ func randomPickOneTableAndTryAutoAnalyze(
rd.Shuffle(len(dbs), func(i, j int) {
dbs[i], dbs[j] = dbs[j], dbs[i]
})
// Query locked tables once to minimize overhead.
// Outdated lock info is acceptable as we verify table lock status pre-analysis.
lockedTables, err := lockstats.QueryLockedTables(sctx)
if err != nil {
statslogutil.StatsLogger().Error(
"check table lock failed",
zap.Error(err),
)
return false
}

for _, db := range dbs {
// Ignore the memory and system database.
if util.IsMemOrSysDB(strings.ToLower(db)) {
Expand All @@ -394,16 +390,6 @@ func randomPickOneTableAndTryAutoAnalyze(
tbls[i], tbls[j] = tbls[j], tbls[i]
})

tidsAndPids := getAllTidsAndPids(tbls)
lockedTables, err := statsHandle.GetLockedTables(tidsAndPids...)
if err != nil {
statslogutil.StatsLogger().Error(
"check table lock failed",
zap.Error(err),
)
continue
}

// We need to check every partition of every table to see if it needs to be analyzed.
for _, tbl := range tbls {
// If table locked, skip analyze all partitions of the table.
Expand Down
27 changes: 27 additions & 0 deletions pkg/statistics/handle/autoanalyze/autoanalyze_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,33 @@ import (
"go.uber.org/mock/gomock"
)

func TestAutoAnalyzeLockedTable(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t (a int)")
tk.MustExec("insert into t values (1)")
h := dom.StatsHandle()
err := h.HandleDDLEvent(<-h.DDLEventCh())
require.NoError(t, err)
require.NoError(t, h.DumpStatsDeltaToKV(true))
// Lock the table.
tk.MustExec("lock stats t")
is := dom.InfoSchema()
require.NoError(t, h.Update(is))
autoanalyze.AutoAnalyzeMinCnt = 0
defer func() {
autoanalyze.AutoAnalyzeMinCnt = 1000
}()
// Try to analyze the locked table, it should not analyze the table.
require.False(t, dom.StatsHandle().HandleAutoAnalyze(dom.InfoSchema()))

// Unlock the table.
tk.MustExec("unlock stats t")
// Try again, it should analyze the table.
require.True(t, dom.StatsHandle().HandleAutoAnalyze(dom.InfoSchema()))
}

func TestDisableAutoAnalyze(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
Expand Down

0 comments on commit 23953a7

Please sign in to comment.