[ 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)