3232import org .apache .doris .thrift .TGetRealtimeExecStatusRequest ;
3333import org .apache .doris .thrift .TGetRealtimeExecStatusResponse ;
3434import org .apache .doris .thrift .TNetworkAddress ;
35+ import org .apache .doris .thrift .TQueryStatistics ;
3536import org .apache .doris .thrift .TStatusCode ;
3637import org .apache .doris .thrift .TUniqueId ;
3738
39+ import com .google .common .base .Preconditions ;
3840import com .google .common .base .Strings ;
3941import com .google .common .collect .Lists ;
4042import com .google .common .collect .Maps ;
@@ -253,7 +255,7 @@ public List<List<String>> getQueryInfoByColumnNameList(List<String> columnNameLi
253255 }
254256
255257 private static TGetRealtimeExecStatusResponse getRealtimeQueryProfile (
256- TUniqueId queryID , TNetworkAddress targetBackend ) {
258+ TUniqueId queryID , String reqType , TNetworkAddress targetBackend ) {
257259 TGetRealtimeExecStatusResponse resp = null ;
258260 BackendService .Client client = null ;
259261
@@ -268,6 +270,7 @@ private static TGetRealtimeExecStatusResponse getRealtimeQueryProfile(
268270 try {
269271 TGetRealtimeExecStatusRequest req = new TGetRealtimeExecStatusRequest ();
270272 req .setId (queryID );
273+ req .setReqType (reqType );
271274 resp = client .getRealtimeExecStatus (req );
272275 } catch (TException e ) {
273276 LOG .warn ("Got exception when getRealtimeExecStatus, query {} backend {}" ,
@@ -293,16 +296,16 @@ private static TGetRealtimeExecStatusResponse getRealtimeQueryProfile(
293296 return null ;
294297 }
295298
296- if (!resp .isSetReportExecStatusParams ()) {
297- LOG .warn ("Invalid GetRealtimeExecStatusResponse, query {}" ,
299+ if (!resp .isSetReportExecStatusParams () && ! resp . isSetQueryStats () ) {
300+ LOG .warn ("Invalid GetRealtimeExecStatusResponse, missing both exec status and query stats. query {}" ,
298301 DebugUtil .printId (queryID ));
299302 return null ;
300303 }
301304
302305 return resp ;
303306 }
304307
305- private List <Future <TGetRealtimeExecStatusResponse >> createFetchRealTimeProfileTasks (String id ) {
308+ private List <Future <TGetRealtimeExecStatusResponse >> createFetchRealTimeProfileTasks (String id , String reqType ) {
306309 // For query, id is queryId, for load, id is LoadLoadingTaskId
307310 class QueryIdAndAddress {
308311 public TUniqueId id ;
@@ -365,18 +368,66 @@ class QueryIdAndAddress {
365368 }
366369
367370 for (QueryIdAndAddress idAndAddress : involvedBackends ) {
368- Callable <TGetRealtimeExecStatusResponse > task = () -> {
369- return getRealtimeQueryProfile (idAndAddress .id , idAndAddress .beAddress );
370- };
371+ Callable <TGetRealtimeExecStatusResponse > task = () -> getRealtimeQueryProfile (idAndAddress .id ,
372+ reqType , idAndAddress .beAddress );
371373 Future <TGetRealtimeExecStatusResponse > future = fetchRealTimeProfileExecutor .submit (task );
372374 futures .add (future );
373375 }
374376
375377 return futures ;
376378 }
377379
380+ public TQueryStatistics getQueryStatistic (String queryId ) throws Exception {
381+ List <Future <TGetRealtimeExecStatusResponse >> futures = createFetchRealTimeProfileTasks (queryId ,
382+ "stats" );
383+ List <TQueryStatistics > queryStatisticsList = Lists .newArrayList ();
384+ for (Future <TGetRealtimeExecStatusResponse > future : futures ) {
385+ try {
386+ TGetRealtimeExecStatusResponse resp = future .get (5 , TimeUnit .SECONDS );
387+ if (resp != null && resp .getStatus ().status_code == TStatusCode .OK && resp .isSetQueryStats ()) {
388+ queryStatisticsList .add (resp .getQueryStats ());
389+ } else {
390+ LOG .warn ("Failed to get real-time query stats, id {}, resp is {}" ,
391+ queryId , resp == null ? "null" : resp .toString ());
392+ throw new Exception ("Failed to get realtime query stats: " + resp .toString ());
393+ }
394+ } catch (Exception e ) {
395+ LOG .warn ("Failed to get real-time query stats, id {}, error: {}" , queryId , e .getMessage (), e );
396+ throw new Exception ("Failed to get realtime query stats: " + e .getMessage ());
397+ }
398+ }
399+ Preconditions .checkState (!queryStatisticsList .isEmpty () && queryStatisticsList .size () == futures .size (),
400+ String .format ("Failed to get real-time stats, id %s, "
401+ + "queryStatisticsList size %d != futures size %d" ,
402+ queryId , queryStatisticsList .size (), futures .size ()));
403+
404+ TQueryStatistics summary = new TQueryStatistics ();
405+ for (TQueryStatistics queryStats : queryStatisticsList ) {
406+ // sum all the statistics
407+ summary .setScanRows (summary .getScanRows () + queryStats .getScanRows ());
408+ summary .setScanBytes (summary .getScanBytes () + queryStats .getScanBytes ());
409+ summary .setReturnedRows (summary .getReturnedRows () + queryStats .getReturnedRows ());
410+ summary .setCpuMs (summary .getCpuMs () + queryStats .getCpuMs ());
411+ summary .setMaxPeakMemoryBytes (Math .max (summary .getMaxPeakMemoryBytes (),
412+ queryStats .getMaxPeakMemoryBytes ()));
413+ summary .setCurrentUsedMemoryBytes (Math .max (summary .getCurrentUsedMemoryBytes (),
414+ queryStats .getCurrentUsedMemoryBytes ()));
415+ summary .setShuffleSendBytes (summary .getShuffleSendBytes () + queryStats .getShuffleSendBytes ());
416+ summary .setShuffleSendRows (summary .getShuffleSendRows () + queryStats .getShuffleSendRows ());
417+ summary .setScanBytesFromLocalStorage (
418+ summary .getScanBytesFromLocalStorage () + queryStats .getScanBytesFromLocalStorage ());
419+ summary .setScanBytesFromRemoteStorage (
420+ summary .getScanBytesFromRemoteStorage () + queryStats .getScanBytesFromRemoteStorage ());
421+ summary .setSpillWriteBytesToLocalStorage (
422+ summary .getSpillWriteBytesToLocalStorage () + queryStats .getSpillWriteBytesToLocalStorage ());
423+ summary .setSpillReadBytesFromLocalStorage (
424+ summary .getSpillReadBytesFromLocalStorage () + queryStats .getSpillReadBytesFromLocalStorage ());
425+ }
426+ return summary ;
427+ }
428+
378429 public String getProfile (String id ) {
379- List <Future <TGetRealtimeExecStatusResponse >> futures = createFetchRealTimeProfileTasks (id );
430+ List <Future <TGetRealtimeExecStatusResponse >> futures = createFetchRealTimeProfileTasks (id , "profile" );
380431 // beAddr of reportExecStatus of QeProcessorImpl is meaningless, so assign a dummy address
381432 // to avoid compile failing.
382433 TNetworkAddress dummyAddr = new TNetworkAddress ();
@@ -1057,3 +1108,4 @@ public void removeProfile(String profileId) {
10571108 }
10581109 }
10591110}
1111+
0 commit comments