You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ab...@apache.org on 2021/11/19 09:44:25 UTC

[hive] branch master updated: HIVE-25509: CLIService.closeOperation should not fail if operation handle is not present (#2627) (Laszlo Bodor reviewed by Mahesh Kumar Behera)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new b76c640  HIVE-25509: CLIService.closeOperation should not fail if operation handle is not present (#2627) (Laszlo Bodor reviewed by Mahesh Kumar Behera)
b76c640 is described below

commit b76c64024ac340c7a1d764f68bac15501b2bc8d6
Author: Bodor Laszlo <bo...@gmail.com>
AuthorDate: Fri Nov 19 10:44:09 2021 +0100

    HIVE-25509: CLIService.closeOperation should not fail if operation handle is not present (#2627) (Laszlo Bodor reviewed by Mahesh Kumar Behera)
---
 .../java/org/apache/hive/jdbc/HiveStatement.java   | 40 +++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java b/jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java
index 609b3d7..ce8197b 100644
--- a/jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java
+++ b/jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java
@@ -195,7 +195,9 @@ public class HiveStatement implements java.sql.Statement {
       if (stmtHandle.isPresent()) {
         TCloseOperationReq closeReq = new TCloseOperationReq(stmtHandle.get());
         TCloseOperationResp closeResp = client.CloseOperation(closeReq);
-        Utils.verifySuccessWithInfo(closeResp.getStatus());
+        if (!checkInvalidOperationHandle(closeResp)) {
+          Utils.verifySuccessWithInfo(closeResp.getStatus());
+        }
       }
     } catch (SQLException e) {
       throw e;
@@ -214,6 +216,42 @@ public class HiveStatement implements java.sql.Statement {
     }
   }
 
+  /**
+   * Invalid OperationHandle is a special case in HS2, which sometimes could be considered as safe to ignore.
+   * For instance: if the client retried due to HIVE-24786, and the retried operation happened to be the
+   * closeOperation, we don't care as the query might have already been removed from HS2's scope.
+   * @return true, if the response from server contains "Invalid OperationHandle"
+   */
+  private boolean checkInvalidOperationHandle(TCloseOperationResp closeResp) {
+    List<String> messages = closeResp.getStatus().getInfoMessages();
+    if (messages != null && messages.size() > 0) {
+      /*
+       * Here we need to handle 2 different cases, which can happen in CLIService.closeOperation, which actually does:
+       * sessionManager.getOperationManager().getOperation(opHandle).getParentSession().closeOperation(opHandle);
+       */
+      String message = messages.get(0);
+      if (message.contains("Invalid OperationHandle")) {
+        /*
+         * This happens when the first request properly removes the operation handle, then second request arrives, calls
+         * sessionManager.getOperationManager().getOperation(opHandle), and it doesn't find the handle.
+         */
+        LOG.warn("'Invalid OperationHandle' on server side (messages: " + messages + ")");
+        return true;
+      } else if (message.contains("Operation does not exist")) {
+        /*
+         * This is an extremely rare case, which represents a race condition when the first and second request
+         * arrives almost at the same time, both can get the OperationHandle instance
+         * from sessionManager's OperationManager, but the second fails, because it cannot get it again from the
+         * session's OperationManager, because it has been already removed in the meantime.
+         */
+        LOG.warn("'Operation does not exist' on server side (messages: " + messages + ")");
+        return true;
+      }
+    }
+
+    return false;
+  }
+
   void closeClientOperation() throws SQLException {
     try {
       closeStatementIfNeeded();