Skip to content

Commit d2edf5c

Browse files
authored
domain: use dedicated lock for expiredTimeStamp4PC (#45802) (#46211)
close #45400
1 parent 5c14437 commit d2edf5c

File tree

3 files changed

+33
-11
lines changed

3 files changed

+33
-11
lines changed

domain/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,16 @@ go_test(
113113
"//metrics",
114114
"//parser/ast",
115115
"//parser/model",
116+
"//parser/mysql",
116117
"//parser/terror",
117118
"//server",
118119
"//session",
120+
"//sessionctx/stmtctx",
119121
"//sessionctx/variable",
120122
"//store/mockstore",
121123
"//testkit",
122124
"//testkit/testsetup",
125+
"//types",
123126
"//util",
124127
"//util/mock",
125128
"@com_github_ngaut_pools//:pools",

domain/domain.go

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,15 @@ type Domain struct {
118118
indexUsageSyncLease time.Duration
119119
dumpFileGcChecker *dumpFileGcChecker
120120
planReplayerHandle *planReplayerHandle
121-
expiredTimeStamp4PC types.Time
122-
logBackupAdvancer *daemon.OwnerDaemon
123-
historicalStatsWorker *HistoricalStatsWorker
124-
ttlJobManager *ttlworker.JobManager
121+
expiredTimeStamp4PC struct {
122+
// let `expiredTimeStamp4PC` use its own lock to avoid any block across domain.Reload()
123+
// and compiler.Compile(), see issue https://github.com/pingcap/tidb/issues/45400
124+
sync.RWMutex
125+
expiredTimeStamp types.Time
126+
}
127+
logBackupAdvancer *daemon.OwnerDaemon
128+
historicalStatsWorker *HistoricalStatsWorker
129+
ttlJobManager *ttlworker.JobManager
125130

126131
serverID uint64
127132
serverIDSession *concurrency.Session
@@ -394,18 +399,18 @@ func (do *Domain) GetSnapshotMeta(startTS uint64) (*meta.Meta, error) {
394399

395400
// ExpiredTimeStamp4PC gets expiredTimeStamp4PC from domain.
396401
func (do *Domain) ExpiredTimeStamp4PC() types.Time {
397-
do.m.Lock()
398-
defer do.m.Unlock()
402+
do.expiredTimeStamp4PC.RLock()
403+
defer do.expiredTimeStamp4PC.RUnlock()
399404

400-
return do.expiredTimeStamp4PC
405+
return do.expiredTimeStamp4PC.expiredTimeStamp
401406
}
402407

403408
// SetExpiredTimeStamp4PC sets the expiredTimeStamp4PC from domain.
404409
func (do *Domain) SetExpiredTimeStamp4PC(time types.Time) {
405-
do.m.Lock()
406-
defer do.m.Unlock()
410+
do.expiredTimeStamp4PC.Lock()
411+
defer do.expiredTimeStamp4PC.Unlock()
407412

408-
do.expiredTimeStamp4PC = time
413+
do.expiredTimeStamp4PC.expiredTimeStamp = time
409414
}
410415

411416
// DDL gets DDL from domain.
@@ -898,7 +903,6 @@ func NewDomain(store kv.Storage, ddlLease time.Duration, statsLease time.Duratio
898903
slowQuery: newTopNSlowQueries(30, time.Hour*24*7, 500),
899904
indexUsageSyncLease: idxUsageSyncLease,
900905
dumpFileGcChecker: &dumpFileGcChecker{gcLease: dumpFileGcLease, paths: []string{GetPlanReplayerDirName(), GetOptimizerTraceDirName()}},
901-
expiredTimeStamp4PC: types.NewTime(types.ZeroCoreTime, mysql.TypeTimestamp, types.DefaultFsp),
902906
mdlCheckTableInfo: &mdlCheckTableInfo{
903907
mu: sync.Mutex{},
904908
jobsVerMap: make(map[int64]int64),
@@ -913,6 +917,7 @@ func NewDomain(store kv.Storage, ddlLease time.Duration, statsLease time.Duratio
913917
do.serverMemoryLimitHandle = servermemorylimit.NewServerMemoryLimitHandle(do.exit)
914918
do.sysProcesses = SysProcesses{mu: &sync.RWMutex{}, procMap: make(map[uint64]sessionctx.Context)}
915919
do.initDomainSysVars()
920+
do.expiredTimeStamp4PC.expiredTimeStamp = types.NewTime(types.ZeroCoreTime, mysql.TypeTimestamp, types.DefaultFsp)
916921
return do
917922
}
918923

domain/domain_test.go

Lines changed: 14 additions & 0 deletions
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)