github-actions[bot] commented on code in PR #68658:
URL: https://github.com/apache/doris/pull/68658#discussion_r4143010094


##########
fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java:
##########
@@ -1141,10 +1142,19 @@ private void parseByNereids() {
     }
 
     public void finalizeQuery() {
-        // The final profile report occurs after be returns the query data, 
and the profile cannot be
-        // received after unregisterQuery(), causing the instance profile to 
be lost, so we should wait
-        // for the profile before unregisterQuery().
-        updateProfile(true);
+        finalizeQuery(false);
+    }
+
+    void finalizeQuery(boolean willRetry) {
+        if (willRetry) {
+            // The next attempt uses a new query ID. Keep its execution 
profiles for the final
+            // Profile decision, but discard the running history entry keyed 
by the old ID.
+            
ProfileManager.getInstance().removeProfileFromHistory(profile.getId());

Review Comment:
   [P1] Keep the Profile open for the outer cloud replan retry too. A 
post-registration dispatch error containing NO_SCAN_NODE_BACKEND_AVAILABLE_MSG 
goes through the early throw in handleQueryWithRetry with willRetry=false, so 
this branch marks the shared Profile finished. queryRetry then starts a new 
query ID on the same StmtExecutor; both of its summary updates return at 
Profile.isQueryFinished, and unregister only marks its ExecutionProfile 
finished. That entry remains until size-triggered GC, while a retained history 
entry still describes the failed ID. Carry the outer retry decision into 
finalization or reset the Profile before the next attempt, and test a 
dispatch-time replan error followed by success.



##########
fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java:
##########
@@ -1141,10 +1142,19 @@ private void parseByNereids() {
     }
 
     public void finalizeQuery() {
-        // The final profile report occurs after be returns the query data, 
and the profile cannot be
-        // received after unregisterQuery(), causing the instance profile to 
be lost, so we should wait
-        // for the profile before unregisterQuery().
-        updateProfile(true);
+        finalizeQuery(false);
+    }
+
+    void finalizeQuery(boolean willRetry) {
+        if (willRetry) {

Review Comment:
   [P2] Do not let an abandoned dispatch keep the successful retry's profile 
incomplete. Real ExecutionProfiles start with nonempty fragment IDs and zero 
expected backend reports; if dispatch fails before fragments are sent, 
isCompleted() stays false. Retaining that attempt here makes 
Profile.shouldStoreToStorage wait the spill timeout and then mark the final 
successful profile INCOMPLETE even when its own backend reports finished. The 
new retry tests use empty fragment lists, for which isCompleted() is always 
true. Exclude the abandoned attempt from completion accounting or mark it 
terminal, and cover a nonempty failed attempt.



##########
fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java:
##########
@@ -1141,10 +1142,19 @@ private void parseByNereids() {
     }
 
     public void finalizeQuery() {
-        // The final profile report occurs after be returns the query data, 
and the profile cannot be
-        // received after unregisterQuery(), causing the instance profile to 
be lost, so we should wait
-        // for the profile before unregisterQuery().
-        updateProfile(true);
+        finalizeQuery(false);
+    }
+
+    void finalizeQuery(boolean willRetry) {
+        if (willRetry) {
+            // The next attempt uses a new query ID. Keep its execution 
profiles for the final

Review Comment:
   [P2] Render the successful retry's merged query profile. Keeping the failed 
attempt here makes executionProfiles.size() equal two, while 
Profile.getExecutionProfileContent only builds MergedProfile, fills 
rowsProducedMap, and annotates PhysicalPlan actual rows when the size is one. 
Thus a retained successful retry loses its normal merged runtime view and 
actual row counts in both REST and stored profiles. Show the last successful 
attempt's merged view while preserving earlier attempts separately, and assert 
profile text in a retry test.



##########
fe/fe-core/src/main/java/org/apache/doris/common/profile/ProfileManager.java:
##########
@@ -798,32 +794,32 @@ protected void deleteOutdatedProfilesFromStorage() {
         }
 
         try {
-            List<ProfileElement> queryIdToBeRemoved = Lists.newArrayList();
+            List<ProfileElement> profilesToBeRemoved = Lists.newArrayList();
             readLock.lock();
             try {
-                queryIdToBeRemoved = getProfilesToBeRemoved();
+                profilesToBeRemoved = getProfilesToBeRemoved();
             } finally {
                 readLock.unlock();
             }
 
-            if (queryIdToBeRemoved.isEmpty()) {
+            if (profilesToBeRemoved.isEmpty()) {
                 return;
             }
 
             // Archive or delete profiles based on configuration
             if (Config.enable_profile_archive) {
                 // Move profiles to pending directory for archiving
-                moveProfilesToArchivePending(queryIdToBeRemoved);

Review Comment:
   [P2] Handle Broker Load IDs when pruning stored profiles. This is 
pre-existing: a Broker Load profile uses its decimal job ID, but after deleting 
or archiving the selected files this loop parses that ID as a TUniqueId on the 
next line. The parser throws for a decimal ID, so the outer catch stops cleanup 
and later selected profiles remain indexed although their files were already 
removed or moved. Remove each attached execution by its own query ID, as memory 
eviction does, and cover mixed query/load profiles.



##########
fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java:
##########
@@ -1303,12 +1314,13 @@ private void handleQueryWithRetry(TUniqueId queryId) 
throws Exception {
                 }
                 if (i != retryTime - 1 && isNeedRetry && 
context.getProtocolAdapter().canRetryQuery(context)) {
                     LOG.warn("retry {} times. stmt: {}", (i + 1), 
parsedStmt.getOrigStmt().originStmt);
+                    willRetry = true;
                 } else {
                     throw e;
                 }
             } finally {

Review Comment:
   [P2] Clean the failed Flight SQL attempt on an outer cloud replan retry. 
This is pre-existing: Flight beforeQuery switches results to the backends 
before registration, so a post-registration replan error makes 
isReturnResultFromLocal false and skips this finalization call. The failed 
attempt never reaches deferForArrowFlight, while beforeAttempt and request 
close act on the later query ID; its QeProcessor registration, execution 
profile, and finish callbacks remain. This differs from the local-result outer 
retry, which finalizes too early. Unregister the abandoned ID before replanning 
and cover this Flight path.



##########
fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java:
##########
@@ -1141,10 +1142,19 @@ private void parseByNereids() {
     }
 
     public void finalizeQuery() {
-        // The final profile report occurs after be returns the query data, 
and the profile cannot be
-        // received after unregisterQuery(), causing the instance profile to 
be lost, so we should wait
-        // for the profile before unregisterQuery().
-        updateProfile(true);
+        finalizeQuery(false);
+    }
+
+    void finalizeQuery(boolean willRetry) {
+        if (willRetry) {
+            // The next attempt uses a new query ID. Keep its execution 
profiles for the final
+            // Profile decision, but discard the running history entry keyed 
by the old ID.
+            
ProfileManager.getInstance().removeProfileFromHistory(profile.getId());
+        } else {
+            // The final profile report occurs after BE returns the query 
data. Update the profile
+            // before unregistering, or the instance profile can be lost.

Review Comment:
   [P2] Apply the configured query duration threshold after the final retry 
without multiplying it by retry count. This deferred finish keeps two 
ExecutionProfiles; Profile.updateSummary compares a 12-second query (11-second 
failed dispatch plus 1-second successful retry) against 2 * 
auto_profile_threshold_ms. At a 10-second setting the new path drops the whole 
profile, whereas the base retained a profile after the first 11-second attempt. 
Keep any Broker Load per-task policy separate and test a retry whose total 
falls between one and two thresholds.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to