You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2020/08/31 18:34:26 UTC

[impala] 02/03: IMPALA-10065: Fix DCHECK when retrying a query in FINISHED state

This is an automated email from the ASF dual-hosted git repository.

tarmstrong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git

commit 578933fe74d8c320431148f9a458a0051afafb17
Author: stiga-huang <hu...@gmail.com>
AuthorDate: Sun Aug 23 14:18:08 2020 +0800

    IMPALA-10065: Fix DCHECK when retrying a query in FINISHED state
    
    A query will come into the FINISHED state when some rows are available,
    even when some fragment instances are still executing. When a retryable
    query comes into the FINISHED state and the client hasn't fetched any
    results, we are still able to retry it for any retryable failures. This
    patch fixes a DCHECK when retrying a FINISHED state query.
    
    Tests:
     - Add a test in test_query_retries.py for retrying a query in FINISHED
       state.
    
    Change-Id: I11d82bf80640760a47325833463def8a3791bdda
    Reviewed-on: http://gerrit.cloudera.org:8080/16351
    Reviewed-by: Impala Public Jenkins <im...@cloudera.com>
    Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
 be/src/runtime/query-driver.cc             |  5 ++++-
 tests/custom_cluster/test_query_retries.py | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/be/src/runtime/query-driver.cc b/be/src/runtime/query-driver.cc
index 53b35d0..47725a6 100644
--- a/be/src/runtime/query-driver.cc
+++ b/be/src/runtime/query-driver.cc
@@ -127,10 +127,13 @@ void QueryDriver::TryQueryRetry(
 
     // Triggering a retry from the INITIALIZED phase is possible: the
     // cancellation thread pool can kill a query while it is in the INITIALIZATION phase.
+    // Triggering a retry from the FINISHED phase is also possible: the retryable failure
+    // happens after rows are available and before the client fetches any rows.
     ClientRequestState::ExecState exec_state = client_request_state_->exec_state();
     DCHECK(exec_state == ClientRequestState::ExecState::INITIALIZED
         || exec_state == ClientRequestState::ExecState::PENDING
-        || exec_state == ClientRequestState::ExecState::RUNNING)
+        || exec_state == ClientRequestState::ExecState::RUNNING
+        || exec_state == ClientRequestState::ExecState::FINISHED)
         << Substitute(
             "Illegal state: $0", ClientRequestState::ExecStateToString(exec_state));
 
diff --git a/tests/custom_cluster/test_query_retries.py b/tests/custom_cluster/test_query_retries.py
index e41544c..e7bd0d3 100644
--- a/tests/custom_cluster/test_query_retries.py
+++ b/tests/custom_cluster/test_query_retries.py
@@ -496,6 +496,27 @@ class TestQueryRetries(CustomClusterTestSuite):
         assert "Cancelled" in str(e)
 
   @pytest.mark.execute_serially
+  def test_retry_finished_query(self):
+    """Test that queries in FINISHED state can still be retried before the client fetch
+    any rows. Sets batch_size to 1 so results will be available as soon as possible.
+    The query state becomes FINISHED when results are available."""
+    query = "select * from functional.alltypes where bool_col = sleep(50)"
+    handle = self.execute_query_async(query,
+        query_options={'retry_failed_queries': 'true', 'batch_size': '1'})
+    self.wait_for_state(handle, self.client.QUERY_STATES['FINISHED'], 60)
+
+    self.__kill_random_impalad()
+    time.sleep(5)
+
+    self.client.fetch(query, handle)
+
+    # Verifies the query is retried.
+    retried_query_id = self.__get_retried_query_id_from_summary(handle)
+    assert retried_query_id is not None
+
+    self.client.close_query(handle)
+
+  @pytest.mark.execute_serially
   @CustomClusterTestSuite.with_args(
       statestored_args="-statestore_heartbeat_frequency_ms=60000")
   def test_retry_query_cancel(self):