statistics: fix panic when to enable force-init-stats (#51357)
close pingcap/tidb#51358
This commit is contained in:
@ -165,10 +165,10 @@ func (h *Handle) initStatsHistograms4Chunk(is infoschema.InfoSchema, cache stats
|
||||
for row := iter.Begin(); row != iter.End(); row = iter.Next() {
|
||||
tblID, statsVer := row.GetInt64(0), row.GetInt64(8)
|
||||
table, ok := cache.Get(tblID)
|
||||
table = table.Copy()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
table = table.Copy()
|
||||
id, ndv, nullCount, version, totColSize := row.GetInt64(2), row.GetInt64(3), row.GetInt64(5), row.GetUint64(4), row.GetInt64(7)
|
||||
lastAnalyzePos := row.GetDatum(11, types.NewFieldType(mysql.TypeBlob))
|
||||
tbl, _ := h.TableInfoByID(is, table.PhysicalID)
|
||||
|
||||
1
pkg/statistics/handle/cache/BUILD.bazel
vendored
1
pkg/statistics/handle/cache/BUILD.bazel
vendored
@ -30,6 +30,7 @@ go_library(
|
||||
"//pkg/util/logutil",
|
||||
"//pkg/util/syncutil",
|
||||
"@com_github_pingcap_errors//:errors",
|
||||
"@com_github_pingcap_failpoint//:failpoint",
|
||||
"@org_uber_go_zap//:zap",
|
||||
],
|
||||
)
|
||||
|
||||
4
pkg/statistics/handle/cache/statscache.go
vendored
4
pkg/statistics/handle/cache/statscache.go
vendored
@ -19,6 +19,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/pingcap/errors"
|
||||
"github.com/pingcap/failpoint"
|
||||
"github.com/pingcap/tidb/pkg/config"
|
||||
"github.com/pingcap/tidb/pkg/infoschema"
|
||||
tidbmetrics "github.com/pingcap/tidb/pkg/metrics"
|
||||
@ -204,6 +205,9 @@ func (s *StatsCacheImpl) MemConsumed() (size int64) {
|
||||
|
||||
// Get returns the specified table's stats.
|
||||
func (s *StatsCacheImpl) Get(tableID int64) (*statistics.Table, bool) {
|
||||
failpoint.Inject("StatsCacheGetNil", func() {
|
||||
failpoint.Return(nil, false)
|
||||
})
|
||||
return s.Load().Get(tableID)
|
||||
}
|
||||
|
||||
|
||||
@ -9,13 +9,14 @@ go_test(
|
||||
],
|
||||
flaky = True,
|
||||
race = "on",
|
||||
shard_count = 8,
|
||||
shard_count = 9,
|
||||
deps = [
|
||||
"//pkg/config",
|
||||
"//pkg/parser/model",
|
||||
"//pkg/statistics/handle/internal",
|
||||
"//pkg/testkit",
|
||||
"//pkg/testkit/testsetup",
|
||||
"@com_github_pingcap_failpoint//:failpoint",
|
||||
"@com_github_stretchr_testify//require",
|
||||
"@org_uber_go_goleak//:goleak",
|
||||
],
|
||||
|
||||
@ -19,6 +19,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pingcap/failpoint"
|
||||
"github.com/pingcap/tidb/pkg/config"
|
||||
"github.com/pingcap/tidb/pkg/parser/model"
|
||||
"github.com/pingcap/tidb/pkg/statistics/handle/internal"
|
||||
@ -237,6 +238,33 @@ func TestInitStats(t *testing.T) {
|
||||
h.SetLease(0)
|
||||
}
|
||||
|
||||
func TestInitStats51358(t *testing.T) {
|
||||
originValue := config.GetGlobalConfig().Performance.LiteInitStats
|
||||
defer func() {
|
||||
config.GetGlobalConfig().Performance.LiteInitStats = originValue
|
||||
}()
|
||||
config.GetGlobalConfig().Performance.LiteInitStats = false
|
||||
store, dom := testkit.CreateMockStoreAndDomain(t)
|
||||
testKit := testkit.NewTestKit(t, store)
|
||||
testKit.MustExec("use test")
|
||||
testKit.MustExec("set @@session.tidb_analyze_version = 1")
|
||||
testKit.MustExec("create table t(a int, b int, c int, primary key(a), key idx(b))")
|
||||
testKit.MustExec("insert into t values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,7,8)")
|
||||
testKit.MustExec("analyze table t")
|
||||
h := dom.StatsHandle()
|
||||
is := dom.InfoSchema()
|
||||
// `Update` will not use load by need strategy when `Lease` is 0, and `InitStats` is only called when
|
||||
// `Lease` is not 0, so here we just change it.
|
||||
h.SetLease(time.Millisecond)
|
||||
|
||||
h.Clear()
|
||||
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/statistics/handle/cache/StatsCacheGetNil", "return()"))
|
||||
defer func() {
|
||||
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/statistics/handle/cache/StatsCacheGetNil"))
|
||||
}()
|
||||
require.NoError(t, h.InitStats(is))
|
||||
}
|
||||
|
||||
func TestInitStatsVer2(t *testing.T) {
|
||||
originValue := config.GetGlobalConfig().Performance.LiteInitStats
|
||||
defer func() {
|
||||
|
||||
Reference in New Issue
Block a user