Skip to content

Commit

Permalink
statistics: fix data race in the Handle.IsTableLocked (#40572)
Browse files Browse the repository at this point in the history
close #40567
  • Loading branch information
hawkingrei authored Jan 17, 2023
1 parent aa51b46 commit b9fb22d
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 3 deletions.
2 changes: 2 additions & 0 deletions statistics/handle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ go_library(
"//util/memory",
"//util/ranger",
"//util/sqlexec",
"//util/syncutil",
"//util/timeutil",
"@com_github_ngaut_pools//:pools",
"@com_github_pingcap_errors//:errors",
Expand Down Expand Up @@ -72,6 +73,7 @@ go_test(
],
embed = [":handle"],
flaky = True,
race = "on",
shard_count = 50,
deps = [
"//config",
Expand Down
12 changes: 10 additions & 2 deletions statistics/handle/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import (
"github.com/pingcap/tidb/util/mathutil"
"github.com/pingcap/tidb/util/memory"
"github.com/pingcap/tidb/util/sqlexec"
"github.com/pingcap/tidb/util/syncutil"
"github.com/prometheus/client_golang/prometheus"
"github.com/tikv/client-go/v2/oracle"
atomic2 "go.uber.org/atomic"
Expand All @@ -70,7 +71,7 @@ type Handle struct {
initStatsCtx sessionctx.Context

mu struct {
sync.RWMutex
syncutil.RWMutex
ctx sessionctx.Context
// rateMap contains the error rate delta from feedback.
rateMap errorRateDeltaMap
Expand Down Expand Up @@ -361,8 +362,15 @@ func (h *Handle) RemoveLockedTables(tids []int64, pids []int64, tables []*ast.Ta
return "", err
}

// IsTableLocked check whether table is locked in handle
// IsTableLocked check whether table is locked in handle with Handle.Mutex
func (h *Handle) IsTableLocked(tableID int64) bool {
h.mu.RLock()
defer h.mu.RUnlock()
return h.isTableLocked(tableID)
}

// IsTableLocked check whether table is locked in handle without Handle.Mutex
func (h *Handle) isTableLocked(tableID int64) bool {
return isTableLocked(h.tableLocked, tableID)
}

Expand Down
3 changes: 2 additions & 1 deletion statistics/handle/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,8 @@ func (h *Handle) dumpTableStatCountToKV(id int64, delta variable.TableDelta) (up
startTS := txn.StartTS()
updateStatsMeta := func(id int64) error {
var err error
if h.IsTableLocked(id) {
// This lock is already locked on it so it use isTableLocked without lock.
if h.isTableLocked(id) {
if delta.Delta < 0 {
_, err = exec.ExecuteInternal(ctx, "update mysql.stats_table_locked set version = %?, count = count - %?, modify_count = modify_count + %? where table_id = %? and count >= %?", startTS, -delta.Delta, delta.Count, id, -delta.Delta)
} else {
Expand Down

0 comments on commit b9fb22d

Please sign in to comment.