diff --git a/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java b/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java index b4550905fed7..4aa142f52f35 100644 --- a/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java +++ b/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java @@ -319,11 +319,7 @@ public void run() { @Override public Object run() throws HiveSQLException { assert (!parentHive.allowClose()); - try { - Hive.set(parentSessionState.getHiveDb()); - } catch (HiveException e) { - throw new HiveSQLException(e); - } + Hive.set(parentHive); // TODO: can this result in cross-thread reuse of session state? SessionState.setCurrentSessionState(parentSessionState); PerfLogger.setPerfLogger(SessionState.getPerfLogger()); diff --git a/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java b/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java index 8eacf138b8b3..cae9ead05c13 100644 --- a/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java +++ b/service/src/java/org/apache/hive/service/cli/session/HiveSessionImpl.java @@ -401,11 +401,11 @@ private synchronized void acquireAfterOpLock(boolean userAccess) { // set the thread name with the logging prefix. sessionState.updateThreadName(); - try { - setSessionHive(); - } catch (HiveSQLException e) { - throw new RuntimeException(e); - } + // If Hive.get() is being shared across different sessions, + // SessionState#getHiveDb() and Hive.get() may be different, in such case, + // the risk of deadlock on HiveMetaStoreClient#SynchronizedHandler can happen. + // Refresh the thread-local Hive to avoid the problem. + Hive.set(sessionHive); } /** @@ -432,6 +432,14 @@ private synchronized void releaseBeforeOpLock(boolean userAccess) { sessionState.resetThreadName(); } + // We have already set the thread-local Hive belonging to the current session, + // if the thread-local Hive has been changed after running the operation, + // the Hive after should belong to the same session, and we should update the sessionHive. + // The thread-local hive would be closed and recreated only when the underlying + // HiveMetaStoreClient is incompatible with the newest session conf. + if (Hive.getThreadLocal() != null && Hive.getThreadLocal() != sessionHive) { + sessionHive = Hive.getThreadLocal(); + } SessionState.detachSession(); if (ThreadWithGarbageCleanup.currentThread() instanceof ThreadWithGarbageCleanup) { ThreadWithGarbageCleanup currentThread =