@@ -2546,11 +2546,15 @@ func dataForAnalyzeStatusHelper(ctx context.Context, e *memtableRetriever, sctx
25462546 jobInfo := chunkRow .GetString (3 )
25472547 processedRows := chunkRow .GetInt64 (4 )
25482548 var startTime , endTime any
2549+ // startTime and endTime use the local timezone for displaying.
2550+ // startTimeUTC is used to calculate the remaining duration of the job.
2551+ var startTimeUTC * time.Time
25492552 if ! chunkRow .IsNull (5 ) {
25502553 t , err := chunkRow .GetTime (5 ).GoTime (time .UTC )
25512554 if err != nil {
25522555 return nil , err
25532556 }
2557+ startTimeUTC = & t
25542558 startTime = types .NewTime (types .FromGoTime (t .In (sctx .GetSessionVars ().TimeZone )), mysql .TypeDatetime , 0 )
25552559 }
25562560 if ! chunkRow .IsNull (6 ) {
@@ -2574,11 +2578,10 @@ func dataForAnalyzeStatusHelper(ctx context.Context, e *memtableRetriever, sctx
25742578
25752579 var remainDurationStr , progressDouble , estimatedRowCntStr any
25762580 if state == statistics .AnalyzeRunning && ! strings .HasPrefix (jobInfo , "merge global stats" ) {
2577- startTime , ok := startTime .(types.Time )
2578- if ! ok {
2581+ if startTimeUTC == nil {
25792582 return nil , errors .New ("invalid start time" )
25802583 }
2581- remainingDuration , progress , estimatedRowCnt , remainDurationErr := getRemainDurationForAnalyzeStatusHelper (ctx , sctx , & startTime ,
2584+ remainingDuration , progress , estimatedRowCnt , remainDurationErr := getRemainDurationForAnalyzeStatusHelper (ctx , sctx , startTimeUTC ,
25822585 dbName , tableName , partitionName , processedRows )
25832586 if remainDurationErr != nil {
25842587 logutil .BgLogger ().Warn ("get remaining duration failed" , zap .Error (remainDurationErr ))
@@ -2615,16 +2618,13 @@ func dataForAnalyzeStatusHelper(ctx context.Context, e *memtableRetriever, sctx
26152618
26162619func getRemainDurationForAnalyzeStatusHelper (
26172620 ctx context.Context ,
2618- sctx sessionctx.Context , startTime * types .Time ,
2621+ sctx sessionctx.Context , startTimeUTC * time .Time ,
26192622 dbName , tableName , partitionName string , processedRows int64 ,
26202623) (_ * time.Duration , percentage , totalCnt float64 , err error ) {
26212624 remainingDuration := time .Duration (0 )
2622- if startTime != nil {
2623- start , err := startTime .GoTime (time .UTC )
2624- if err != nil {
2625- return nil , percentage , totalCnt , err
2626- }
2627- duration := time .Now ().UTC ().Sub (start )
2625+ if startTimeUTC != nil {
2626+ // time.Time.Sub uses the actual instant.
2627+ duration := time .Since (* startTimeUTC )
26282628 if intest .InTest {
26292629 if val := ctx .Value (AnalyzeProgressTest ); val != nil {
26302630 remainingDuration , percentage = calRemainInfoForAnalyzeStatus (ctx , int64 (totalCnt ), processedRows , duration )
0 commit comments