Skip to content

Commit 188da2d

Browse files
authored
domain: use dedicated lock for expiredTimeStamp4PC (#45802) (#47519)
close #45400
1 parent 76f7ab6 commit 188da2d

File tree

3 files changed

+37
-15
lines changed

3 files changed

+37
-15
lines changed

domain/BUILD.bazel

+3
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,16 @@ go_test(
128128
"//parser/ast",
129129
"//parser/auth",
130130
"//parser/model",
131+
"//parser/mysql",
131132
"//parser/terror",
132133
"//server",
133134
"//session",
135+
"//sessionctx/stmtctx",
134136
"//sessionctx/variable",
135137
"//store/mockstore",
136138
"//testkit",
137139
"//testkit/testsetup",
140+
"//types",
138141
"//util",
139142
"//util/mock",
140143
"//util/replayer",

domain/domain.go

+20-15
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,19 @@ type Domain struct {
146146
memoryUsageAlarmHandle *memoryusagealarm.Handle
147147
serverMemoryLimitHandle *servermemorylimit.Handle
148148
// TODO: use Run for each process in future pr
149-
wg *util.WaitGroupEnhancedWrapper
150-
statsUpdating atomicutil.Int32
151-
cancel context.CancelFunc
152-
indexUsageSyncLease time.Duration
153-
dumpFileGcChecker *dumpFileGcChecker
154-
planReplayerHandle *planReplayerHandle
155-
extractTaskHandle *ExtractHandle
156-
expiredTimeStamp4PC types.Time
149+
wg *util.WaitGroupEnhancedWrapper
150+
statsUpdating atomicutil.Int32
151+
cancel context.CancelFunc
152+
indexUsageSyncLease time.Duration
153+
dumpFileGcChecker *dumpFileGcChecker
154+
planReplayerHandle *planReplayerHandle
155+
extractTaskHandle *ExtractHandle
156+
expiredTimeStamp4PC struct {
157+
// let `expiredTimeStamp4PC` use its own lock to avoid any block across domain.Reload()
158+
// and compiler.Compile(), see issue https://github.com/pingcap/tidb/issues/45400
159+
sync.RWMutex
160+
expiredTimeStamp types.Time
161+
}
157162
logBackupAdvancer *daemon.OwnerDaemon
158163
historicalStatsWorker *HistoricalStatsWorker
159164
ttlJobManager atomic.Pointer[ttlworker.JobManager]
@@ -472,18 +477,18 @@ func (do *Domain) GetSnapshotMeta(startTS uint64) (*meta.Meta, error) {
472477

473478
// ExpiredTimeStamp4PC gets expiredTimeStamp4PC from domain.
474479
func (do *Domain) ExpiredTimeStamp4PC() types.Time {
475-
do.m.Lock()
476-
defer do.m.Unlock()
480+
do.expiredTimeStamp4PC.RLock()
481+
defer do.expiredTimeStamp4PC.RUnlock()
477482

478-
return do.expiredTimeStamp4PC
483+
return do.expiredTimeStamp4PC.expiredTimeStamp
479484
}
480485

481486
// SetExpiredTimeStamp4PC sets the expiredTimeStamp4PC from domain.
482487
func (do *Domain) SetExpiredTimeStamp4PC(time types.Time) {
483-
do.m.Lock()
484-
defer do.m.Unlock()
488+
do.expiredTimeStamp4PC.Lock()
489+
defer do.expiredTimeStamp4PC.Unlock()
485490

486-
do.expiredTimeStamp4PC = time
491+
do.expiredTimeStamp4PC.expiredTimeStamp = time
487492
}
488493

489494
// DDL gets DDL from domain.
@@ -1021,7 +1026,6 @@ func NewDomain(store kv.Storage, ddlLease time.Duration, statsLease time.Duratio
10211026
slowQuery: newTopNSlowQueries(30, time.Hour*24*7, 500),
10221027
indexUsageSyncLease: idxUsageSyncLease,
10231028
dumpFileGcChecker: &dumpFileGcChecker{gcLease: dumpFileGcLease, paths: []string{replayer.GetPlanReplayerDirName(), GetOptimizerTraceDirName(), GetExtractTaskDirName()}},
1024-
expiredTimeStamp4PC: types.NewTime(types.ZeroCoreTime, mysql.TypeTimestamp, types.DefaultFsp),
10251029
mdlCheckTableInfo: &mdlCheckTableInfo{
10261030
mu: sync.Mutex{},
10271031
jobsVerMap: make(map[int64]int64),
@@ -1037,6 +1041,7 @@ func NewDomain(store kv.Storage, ddlLease time.Duration, statsLease time.Duratio
10371041
do.serverMemoryLimitHandle = servermemorylimit.NewServerMemoryLimitHandle(do.exit)
10381042
do.sysProcesses = SysProcesses{mu: &sync.RWMutex{}, procMap: make(map[uint64]sessionctx.Context)}
10391043
do.initDomainSysVars()
1044+
do.expiredTimeStamp4PC.expiredTimeStamp = types.NewTime(types.ZeroCoreTime, mysql.TypeTimestamp, types.DefaultFsp)
10401045
return do
10411046
}
10421047

domain/domain_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ import (
3434
"github.com/pingcap/tidb/metrics"
3535
"github.com/pingcap/tidb/parser/ast"
3636
"github.com/pingcap/tidb/parser/model"
37+
"github.com/pingcap/tidb/parser/mysql"
38+
"github.com/pingcap/tidb/sessionctx/stmtctx"
3739
"github.com/pingcap/tidb/sessionctx/variable"
3840
"github.com/pingcap/tidb/store/mockstore"
41+
"github.com/pingcap/tidb/types"
3942
"github.com/pingcap/tidb/util/mock"
4043
dto "github.com/prometheus/client_model/go"
4144
"github.com/stretchr/testify/require"
@@ -187,6 +190,17 @@ func TestStatWorkRecoverFromPanic(t *testing.T) {
187190
scope := dom.GetScope("status")
188191
require.Equal(t, variable.DefaultStatusVarScopeFlag, scope)
189192

193+
// default expiredTimeStamp4PC = "0000-00-00 00:00:00"
194+
ts := types.NewTime(types.ZeroCoreTime, mysql.TypeTimestamp, types.DefaultFsp)
195+
expiredTimeStamp := dom.ExpiredTimeStamp4PC()
196+
require.Equal(t, expiredTimeStamp, ts)
197+
198+
// set expiredTimeStamp4PC to "2023-08-02 12:15:00"
199+
ts, _ = types.ParseTimestamp(&stmtctx.StatementContext{TimeZone: time.UTC}, "2023-08-02 12:15:00")
200+
dom.SetExpiredTimeStamp4PC(ts)
201+
expiredTimeStamp = dom.ExpiredTimeStamp4PC()
202+
require.Equal(t, expiredTimeStamp, ts)
203+
190204
err = store.Close()
191205
require.NoError(t, err)
192206

0 commit comments

Comments
 (0)