[ 
https://issues.apache.org/jira/browse/HIVE-27201?focusedWorklogId=858528&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-858528
 ]

ASF GitHub Bot logged work on HIVE-27201:
-----------------------------------------

                Author: ASF GitHub Bot
            Created on: 22/Apr/23 00:14
            Start Date: 22/Apr/23 00:14
    Worklog Time Spent: 10m 
      Work Description: saihemanth-cloudera commented on code in PR #4180:
URL: https://github.com/apache/hive/pull/4180#discussion_r1174233514


##########
itests/hive-unit/src/test/java/org/apache/hive/service/server/TestHS2SessionHive.java:
##########
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hive.service.server;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.metastore.DefaultMetaStoreFilterHookImpl;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.TableMeta;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
+import org.apache.hadoop.hive.ql.metadata.Hive;
+import org.apache.hadoop.hive.ql.session.SessionState;
+import org.apache.hive.jdbc.HiveConnection;
+import org.apache.hive.jdbc.miniHS2.MiniHS2;
+import org.apache.hive.service.rpc.thrift.TCLIService;
+import org.apache.hive.service.rpc.thrift.TGetTablesReq;
+import org.apache.hive.service.rpc.thrift.TGetTablesResp;
+import org.apache.hive.service.rpc.thrift.TSessionHandle;
+import org.apache.hive.service.rpc.thrift.TStatusCode;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
+import java.lang.reflect.Field;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Test for HIVE-27201
+ */
+public class TestHS2SessionHive {
+
+  private static MiniHS2 miniHS2 = null;
+
+  public static class DummyFilterHook extends DefaultMetaStoreFilterHookImpl {
+    private static Map<String, Hive> threadHiveMap = new ConcurrentHashMap<>();
+    private static Set<String> totalThreadCalls = 
Collections.synchronizedSet(new HashSet<>());
+
+    public DummyFilterHook(Configuration conf) {
+      super(conf);
+    }
+
+    @Override
+    public List<TableMeta> filterTableMetas(String catName, String dbName, 
List<TableMeta> tableMetas)
+        throws MetaException {
+      try {
+        Assert.assertNotNull(SessionState.get());
+        totalThreadCalls.add(Thread.currentThread().getName());
+        synchronized (totalThreadCalls) {
+          totalThreadCalls.notifyAll();
+        }
+        synchronized (threadHiveMap) {
+          threadHiveMap.wait();
+        }
+        Hive localHive = Hive.get();
+        threadHiveMap.put(Thread.currentThread().getName(), localHive);
+        for (TableMeta tableMeta : tableMetas) {
+          localHive.getTable(tableMeta.getDbName(), tableMeta.getTableName());
+        }
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+      return super.filterTableMetas(catName, dbName, tableMetas);
+    }
+  }
+
+  @Test
+  public void testSessionHive() throws Exception {
+    Client client1 = newClient(), client2 = newClient();
+    Task task1 = new Task("task1", client1.client, client2.sessionHandle),
+         task2 = new Task("task2", client2.client, client1.sessionHandle);
+
+    while (DummyFilterHook.totalThreadCalls.size() < 2) {
+      synchronized (DummyFilterHook.totalThreadCalls) {
+        DummyFilterHook.totalThreadCalls.wait();
+      }
+    }
+    Thread.sleep(100);
+    synchronized (DummyFilterHook.threadHiveMap) {
+      DummyFilterHook.threadHiveMap.notifyAll();
+    }
+    Thread.sleep(3000L);
+    // Check to see if there are any deadlocks
+    ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
+    Assert.assertNull(threadBean.findDeadlockedThreads());
+    task1.join();
+    task2.join();
+    Assert.assertTrue(task1.result);
+    Assert.assertTrue(task2.result);
+  }
+
+  private class Task extends Thread {
+    TCLIService.Iface client;
+    TSessionHandle sessionHandle;
+    boolean result;
+    Task(String threadName,
+         TCLIService.Iface client,
+         TSessionHandle sessionHandle) {
+      this.client = client;
+      this.sessionHandle = sessionHandle;
+      this.result = false;
+      this.setName(threadName);
+      this.setDaemon(true);
+      this.start();
+    }
+
+    @Override
+    public void run() {
+      try {
+        TGetTablesReq getTablesReq = new TGetTablesReq(sessionHandle);
+        getTablesReq.setCatalogName("hive");
+        getTablesReq.setSchemaName("*");
+        getTablesReq.setTableName("*");
+        TGetTablesResp resp = client.GetTables(getTablesReq);
+        result = resp.getStatus().getStatusCode() == 
TStatusCode.SUCCESS_STATUS;
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  private static class Client {
+    TCLIService.Iface client;
+    TSessionHandle sessionHandle;
+  }
+
+  private Client newClient() throws Exception {
+    Connection conn = DriverManager.
+        getConnection(miniHS2.getJdbcURL(), System.getProperty("user.name"), 
"");
+    Field clientField = HiveConnection.class.getDeclaredField("client");
+    Field sesHanField = HiveConnection.class.getDeclaredField("sessHandle");

Review Comment:
   Do you mean sessionField?





Issue Time Tracking
-------------------

    Worklog Id:     (was: 858528)
    Time Spent: 3h 20m  (was: 3h 10m)

> Inconsistency between session Hive and thread-local Hive may cause HS2 
> deadlock
> -------------------------------------------------------------------------------
>
>                 Key: HIVE-27201
>                 URL: https://issues.apache.org/jira/browse/HIVE-27201
>             Project: Hive
>          Issue Type: Bug
>          Components: HiveServer2
>            Reporter: Zhihua Deng
>            Assignee: Zhihua Deng
>            Priority: Major
>              Labels: pull-request-available
>          Time Spent: 3h 20m
>  Remaining Estimate: 0h
>
> The HiveServer2’s server handler can switch to process the operation from 
> other session, in such case, the Hive cached in ThreadLocal is not the same 
> as the Hive in SessionState, and can be referenced by another session. 
> If the two handlers swap their sessions to process the DatabaseMetaData 
> request, and the HiveMetastoreClientFactory obtains the Hive via Hive.get(), 
> then there is a chance that the deadlock can happen.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to