diff --git a/domain/BUILD.bazel b/domain/BUILD.bazel index 68b076f87ff66..d1001013a1953 100644 --- a/domain/BUILD.bazel +++ b/domain/BUILD.bazel @@ -128,13 +128,16 @@ go_test( "//parser/ast", "//parser/auth", "//parser/model", + "//parser/mysql", "//parser/terror", "//server", "//session", + "//sessionctx/stmtctx", "//sessionctx/variable", "//store/mockstore", "//testkit", "//testkit/testsetup", + "//types", "//util", "//util/mock", "//util/replayer", diff --git a/domain/domain.go b/domain/domain.go index e6ee52da1c860..a06adca5033ec 100644 --- a/domain/domain.go +++ b/domain/domain.go @@ -146,6 +146,7 @@ type Domain struct { memoryUsageAlarmHandle *memoryusagealarm.Handle serverMemoryLimitHandle *servermemorylimit.Handle // TODO: use Run for each process in future pr +<<<<<<< HEAD wg *util.WaitGroupEnhancedWrapper statsUpdating atomicutil.Int32 cancel context.CancelFunc @@ -157,6 +158,28 @@ type Domain struct { logBackupAdvancer *daemon.OwnerDaemon historicalStatsWorker *HistoricalStatsWorker ttlJobManager atomic.Pointer[ttlworker.JobManager] +======= + wg *util.WaitGroupEnhancedWrapper + statsUpdating atomicutil.Int32 + cancel context.CancelFunc + indexUsageSyncLease time.Duration + dumpFileGcChecker *dumpFileGcChecker + planReplayerHandle *planReplayerHandle + extractTaskHandle *ExtractHandle + expiredTimeStamp4PC struct { + // let `expiredTimeStamp4PC` use its own lock to avoid any block across domain.Reload() + // and compiler.Compile(), see issue https://github.com/pingcap/tidb/issues/45400 + sync.RWMutex + expiredTimeStamp types.Time + } + + logBackupAdvancer *daemon.OwnerDaemon + historicalStatsWorker *HistoricalStatsWorker + ttlJobManager atomic.Pointer[ttlworker.JobManager] + runawayManager *resourcegroup.RunawayManager + runawaySyncer *runawaySyncer + resourceGroupsController *rmclient.ResourceGroupsController +>>>>>>> 29727caacb8 (domain: use dedicated lock for expiredTimeStamp4PC (#45802)) serverID uint64 serverIDSession *concurrency.Session @@ -472,18 +495,18 @@ func (do *Domain) GetSnapshotMeta(startTS uint64) (*meta.Meta, error) { // ExpiredTimeStamp4PC gets expiredTimeStamp4PC from domain. func (do *Domain) ExpiredTimeStamp4PC() types.Time { - do.m.Lock() - defer do.m.Unlock() + do.expiredTimeStamp4PC.RLock() + defer do.expiredTimeStamp4PC.RUnlock() - return do.expiredTimeStamp4PC + return do.expiredTimeStamp4PC.expiredTimeStamp } // SetExpiredTimeStamp4PC sets the expiredTimeStamp4PC from domain. func (do *Domain) SetExpiredTimeStamp4PC(time types.Time) { - do.m.Lock() - defer do.m.Unlock() + do.expiredTimeStamp4PC.Lock() + defer do.expiredTimeStamp4PC.Unlock() - do.expiredTimeStamp4PC = time + do.expiredTimeStamp4PC.expiredTimeStamp = time } // DDL gets DDL from domain. @@ -1021,7 +1044,6 @@ func NewDomain(store kv.Storage, ddlLease time.Duration, statsLease time.Duratio slowQuery: newTopNSlowQueries(30, time.Hour*24*7, 500), indexUsageSyncLease: idxUsageSyncLease, dumpFileGcChecker: &dumpFileGcChecker{gcLease: dumpFileGcLease, paths: []string{replayer.GetPlanReplayerDirName(), GetOptimizerTraceDirName(), GetExtractTaskDirName()}}, - expiredTimeStamp4PC: types.NewTime(types.ZeroCoreTime, mysql.TypeTimestamp, types.DefaultFsp), mdlCheckTableInfo: &mdlCheckTableInfo{ mu: sync.Mutex{}, jobsVerMap: make(map[int64]int64), @@ -1037,6 +1059,7 @@ func NewDomain(store kv.Storage, ddlLease time.Duration, statsLease time.Duratio do.serverMemoryLimitHandle = servermemorylimit.NewServerMemoryLimitHandle(do.exit) do.sysProcesses = SysProcesses{mu: &sync.RWMutex{}, procMap: make(map[uint64]sessionctx.Context)} do.initDomainSysVars() + do.expiredTimeStamp4PC.expiredTimeStamp = types.NewTime(types.ZeroCoreTime, mysql.TypeTimestamp, types.DefaultFsp) return do } diff --git a/domain/domain_test.go b/domain/domain_test.go index bd9287fe730ec..5ae256a277fb4 100644 --- a/domain/domain_test.go +++ b/domain/domain_test.go @@ -34,8 +34,11 @@ import ( "github.com/pingcap/tidb/metrics" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/model" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/store/mockstore" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/mock" dto "github.com/prometheus/client_model/go" "github.com/stretchr/testify/require" @@ -187,6 +190,17 @@ func TestStatWorkRecoverFromPanic(t *testing.T) { scope := dom.GetScope("status") require.Equal(t, variable.DefaultStatusVarScopeFlag, scope) + // default expiredTimeStamp4PC = "0000-00-00 00:00:00" + ts := types.NewTime(types.ZeroCoreTime, mysql.TypeTimestamp, types.DefaultFsp) + expiredTimeStamp := dom.ExpiredTimeStamp4PC() + require.Equal(t, expiredTimeStamp, ts) + + // set expiredTimeStamp4PC to "2023-08-02 12:15:00" + ts, _ = types.ParseTimestamp(&stmtctx.StatementContext{TimeZone: time.UTC}, "2023-08-02 12:15:00") + dom.SetExpiredTimeStamp4PC(ts) + expiredTimeStamp = dom.ExpiredTimeStamp4PC() + require.Equal(t, expiredTimeStamp, ts) + err = store.Close() require.NoError(t, err)