Skip to content

Commit

Permalink
statistics: improve statslock test (#45616)
Browse files Browse the repository at this point in the history
ref #44940
  • Loading branch information
hawkingrei authored Jul 27, 2023
1 parent 0ed68bf commit 5f1fa9f
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 117 deletions.
2 changes: 1 addition & 1 deletion statistics/handle/handletest/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ go_test(
],
flaky = True,
race = "on",
shard_count = 47,
shard_count = 45,
deps = [
"//config",
"//domain",
Expand Down
116 changes: 0 additions & 116 deletions statistics/handle/handletest/handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1726,122 +1726,6 @@ func TestUninitializedStatsStatus(t *testing.T) {
checkStatsPseudo()
}

func TestStatsLockAndUnlockTable(t *testing.T) {
restore := config.RestoreFunc()
defer restore()
config.UpdateGlobal(func(conf *config.Config) {
conf.Performance.EnableStatsCacheMemQuota = true
})
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@tidb_analyze_version = 1")
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b varchar(10), index idx_b (b))")
tk.MustExec("analyze table test.t")
tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.Nil(t, err)

handle := domain.GetDomain(tk.Session()).StatsHandle()
tblStats := handle.GetTableStats(tbl.Meta())
for _, col := range tblStats.Columns {
require.True(t, col.IsStatsInitialized())
}
tk.MustExec("lock stats t")

rows := tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows()
num, _ := strconv.Atoi(rows[0][0].(string))
require.Equal(t, num, 1)

tk.MustExec("insert into t(a, b) values(1,'a')")
tk.MustExec("insert into t(a, b) values(2,'b')")

tk.MustExec("analyze table test.t")
tblStats1 := handle.GetTableStats(tbl.Meta())
require.Equal(t, tblStats, tblStats1)

tableLocked1 := handle.GetTableLockedAndClearForTest()
err = handle.LoadLockedTables()
require.Nil(t, err)
tableLocked2 := handle.GetTableLockedAndClearForTest()
require.Equal(t, tableLocked1, tableLocked2)

tk.MustExec("unlock stats t")
rows = tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows()
num, _ = strconv.Atoi(rows[0][0].(string))
require.Equal(t, num, 0)

tk.MustExec("analyze table test.t")
tblStats2 := handle.GetTableStats(tbl.Meta())
require.Equal(t, int64(2), tblStats2.RealtimeCount)
}

func TestStatsLockAndUnlockTables(t *testing.T) {
restore := config.RestoreFunc()
defer restore()
config.UpdateGlobal(func(conf *config.Config) {
conf.Performance.EnableStatsCacheMemQuota = true
})
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@tidb_analyze_version = 1")
tk.MustExec("use test")
tk.MustExec("drop table if exists t1")
tk.MustExec("drop table if exists t2")
tk.MustExec("create table t1(a int, b varchar(10), index idx_b (b))")
tk.MustExec("create table t2(a int, b varchar(10), index idx_b (b))")
tk.MustExec("analyze table test.t1, test.t2")
tbl1, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1"))
require.Nil(t, err)
tbl2, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t2"))
require.Nil(t, err)

handle := domain.GetDomain(tk.Session()).StatsHandle()
tbl1Stats := handle.GetTableStats(tbl1.Meta())
for _, col := range tbl1Stats.Columns {
require.True(t, col.IsStatsInitialized())
}
tbl2Stats := handle.GetTableStats(tbl2.Meta())
for _, col := range tbl2Stats.Columns {
require.True(t, col.IsStatsInitialized())
}

tk.MustExec("lock stats t1, t2")

rows := tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows()
num, _ := strconv.Atoi(rows[0][0].(string))
require.Equal(t, num, 2)

tk.MustExec("insert into t1(a, b) values(1,'a')")
tk.MustExec("insert into t1(a, b) values(2,'b')")

tk.MustExec("insert into t2(a, b) values(1,'a')")
tk.MustExec("insert into t2(a, b) values(2,'b')")

tk.MustExec("analyze table test.t1, test.t2")
tbl1Stats1 := handle.GetTableStats(tbl1.Meta())
require.Equal(t, tbl1Stats, tbl1Stats1)
tbl2Stats1 := handle.GetTableStats(tbl2.Meta())
require.Equal(t, tbl2Stats, tbl2Stats1)

tableLocked1 := handle.GetTableLockedAndClearForTest()
err = handle.LoadLockedTables()
require.Nil(t, err)
tableLocked2 := handle.GetTableLockedAndClearForTest()
require.Equal(t, tableLocked1, tableLocked2)

tk.MustExec("unlock stats test.t1, test.t2")
rows = tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows()
num, _ = strconv.Atoi(rows[0][0].(string))
require.Equal(t, num, 0)

tk.MustExec("analyze table test.t1, test.t2")
tbl1Stats2 := handle.GetTableStats(tbl1.Meta())
require.Equal(t, int64(2), tbl1Stats2.RealtimeCount)
tbl2Stats2 := handle.GetTableStats(tbl2.Meta())
require.Equal(t, int64(2), tbl2Stats2.RealtimeCount)
}

func TestIssue39336(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
Expand Down
20 changes: 20 additions & 0 deletions statistics/handle/handletest/statslock/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
load("@io_bazel_rules_go//go:def.bzl", "go_test")

go_test(
name = "statslock_test",
timeout = "short",
srcs = [
"main_test.go",
"stats_lcok_test.go",
],
flaky = True,
deps = [
"//config",
"//domain",
"//parser/model",
"//testkit",
"//testkit/testsetup",
"@com_github_stretchr_testify//require",
"@org_uber_go_goleak//:goleak",
],
)
33 changes: 33 additions & 0 deletions statistics/handle/handletest/statslock/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2023 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package statslock

import (
"testing"

"github.com/pingcap/tidb/testkit/testsetup"
"go.uber.org/goleak"
)

func TestMain(m *testing.M) {
opts := []goleak.Option{
goleak.IgnoreTopFunction("github.com/golang/glog.(*fileSink).flushDaemon"),
goleak.IgnoreTopFunction("github.com/lestrrat-go/httprc.runFetchWorker"),
goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"),
goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"),
}
testsetup.SetupForCommonTest()
goleak.VerifyTestMain(m, opts...)
}
142 changes: 142 additions & 0 deletions statistics/handle/handletest/statslock/stats_lcok_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright 2023 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package statslock

import (
"strconv"
"testing"

"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/testkit"
"github.com/stretchr/testify/require"
)

func TestStatsLockAndUnlockTable(t *testing.T) {
restore := config.RestoreFunc()
defer restore()
config.UpdateGlobal(func(conf *config.Config) {
conf.Performance.EnableStatsCacheMemQuota = true
})
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@tidb_analyze_version = 1")
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b varchar(10), index idx_b (b))")
tk.MustExec("analyze table test.t")
tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.Nil(t, err)

handle := domain.GetDomain(tk.Session()).StatsHandle()
tblStats := handle.GetTableStats(tbl.Meta())
for _, col := range tblStats.Columns {
require.True(t, col.IsStatsInitialized())
}
tk.MustExec("lock stats t")

rows := tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows()
num, _ := strconv.Atoi(rows[0][0].(string))
require.Equal(t, num, 1)

tk.MustExec("insert into t(a, b) values(1,'a')")
tk.MustExec("insert into t(a, b) values(2,'b')")

tk.MustExec("analyze table test.t")
tblStats1 := handle.GetTableStats(tbl.Meta())
require.Equal(t, tblStats, tblStats1)

tableLocked1 := handle.GetTableLockedAndClearForTest()
err = handle.LoadLockedTables()
require.Nil(t, err)
tableLocked2 := handle.GetTableLockedAndClearForTest()
require.Equal(t, tableLocked1, tableLocked2)

tk.MustExec("unlock stats t")
rows = tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows()
num, _ = strconv.Atoi(rows[0][0].(string))
require.Equal(t, num, 0)

tk.MustExec("analyze table test.t")
tblStats2 := handle.GetTableStats(tbl.Meta())
require.Equal(t, int64(2), tblStats2.RealtimeCount)
}

func TestStatsLockAndUnlockTables(t *testing.T) {
restore := config.RestoreFunc()
defer restore()
config.UpdateGlobal(func(conf *config.Config) {
conf.Performance.EnableStatsCacheMemQuota = true
})
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@tidb_analyze_version = 1")
tk.MustExec("use test")
tk.MustExec("drop table if exists t1")
tk.MustExec("drop table if exists t2")
tk.MustExec("create table t1(a int, b varchar(10), index idx_b (b))")
tk.MustExec("create table t2(a int, b varchar(10), index idx_b (b))")
tk.MustExec("analyze table test.t1, test.t2")
tbl1, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1"))
require.Nil(t, err)
tbl2, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t2"))
require.Nil(t, err)

handle := domain.GetDomain(tk.Session()).StatsHandle()
tbl1Stats := handle.GetTableStats(tbl1.Meta())
for _, col := range tbl1Stats.Columns {
require.True(t, col.IsStatsInitialized())
}
tbl2Stats := handle.GetTableStats(tbl2.Meta())
for _, col := range tbl2Stats.Columns {
require.True(t, col.IsStatsInitialized())
}

tk.MustExec("lock stats t1, t2")

rows := tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows()
num, _ := strconv.Atoi(rows[0][0].(string))
require.Equal(t, num, 2)

tk.MustExec("insert into t1(a, b) values(1,'a')")
tk.MustExec("insert into t1(a, b) values(2,'b')")

tk.MustExec("insert into t2(a, b) values(1,'a')")
tk.MustExec("insert into t2(a, b) values(2,'b')")

tk.MustExec("analyze table test.t1, test.t2")
tbl1Stats1 := handle.GetTableStats(tbl1.Meta())
require.Equal(t, tbl1Stats, tbl1Stats1)
tbl2Stats1 := handle.GetTableStats(tbl2.Meta())
require.Equal(t, tbl2Stats, tbl2Stats1)

tableLocked1 := handle.GetTableLockedAndClearForTest()
err = handle.LoadLockedTables()
require.Nil(t, err)
tableLocked2 := handle.GetTableLockedAndClearForTest()
require.Equal(t, tableLocked1, tableLocked2)

tk.MustExec("unlock stats test.t1, test.t2")
rows = tk.MustQuery("select count(*) from mysql.stats_table_locked").Rows()
num, _ = strconv.Atoi(rows[0][0].(string))
require.Equal(t, num, 0)

tk.MustExec("analyze table test.t1, test.t2")
tbl1Stats2 := handle.GetTableStats(tbl1.Meta())
require.Equal(t, int64(2), tbl1Stats2.RealtimeCount)
tbl2Stats2 := handle.GetTableStats(tbl2.Meta())
require.Equal(t, int64(2), tbl2Stats2.RealtimeCount)
}

0 comments on commit 5f1fa9f

Please sign in to comment.