diff --git a/sqle/model/instance_audit_plan.go b/sqle/model/instance_audit_plan.go index 158bf99c5..eeb098307 100644 --- a/sqle/model/instance_audit_plan.go +++ b/sqle/model/instance_audit_plan.go @@ -176,8 +176,13 @@ func (s *Storage) GetLatestStartTimeAuditPlanSQLV2(sourceId uint, typ string) (s info := struct { StartTime string `gorm:"column:max_start_time"` }{} - err := s.db.Raw(`SELECT MAX(STR_TO_DATE(JSON_UNQUOTE(JSON_EXTRACT(info, '$.start_time_of_last_scraped_sql')), '%Y-%m-%dT%H:%i:%s.%f')) - AS max_start_time FROM sql_manage_records WHERE source_id = ? AND source = ? AND deleted_at is NULL`, sourceId, typ).Scan(&info).Error + // Compatible with DATETIME(6) (space separator) and historical RFC3339-like values (T separator). + // Trailing timezone suffixes on RFC3339 are ignored once the format is exhausted. + err := s.db.Raw(`SELECT MAX(COALESCE( + STR_TO_DATE(JSON_UNQUOTE(JSON_EXTRACT(info, '$.start_time_of_last_scraped_sql')), '%Y-%m-%d %H:%i:%s.%f'), + STR_TO_DATE(JSON_UNQUOTE(JSON_EXTRACT(info, '$.start_time_of_last_scraped_sql')), '%Y-%m-%dT%H:%i:%s.%f'), + STR_TO_DATE(JSON_UNQUOTE(JSON_EXTRACT(info, '$.start_time_of_last_scraped_sql')), '%Y-%m-%d %H:%i:%s') + )) AS max_start_time FROM sql_manage_records WHERE source_id = ? AND source = ? AND deleted_at is NULL`, sourceId, typ).Scan(&info).Error return info.StartTime, err } diff --git a/sqle/server/auditplan/task_wrap.go b/sqle/server/auditplan/task_wrap.go index ff4c03933..88975669c 100644 --- a/sqle/server/auditplan/task_wrap.go +++ b/sqle/server/auditplan/task_wrap.go @@ -101,6 +101,7 @@ type TaskWrapper struct { sync.WaitGroup isStarted bool cancel chan struct{} + cancelOnce sync.Once loopInterval func() time.Duration } @@ -219,7 +220,11 @@ func (at *TaskWrapper) stopCollect() error { if !at.isStarted { return nil } - at.cancel <- struct{}{} + // S2 scheme B: close once so Stop is non-blocking while ExtractSQL is still running. + // loop's `select { case <-cancel: }` unblocks on close; avoid unbuffered send deadlock. + at.cancelOnce.Do(func() { + close(at.cancel) + }) at.isStarted = false at.WaitGroup.Wait() at.logger.Infof("stop task")