This is an automated email from the ASF dual-hosted git repository.
krisztiankasa 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 52b6fc322e0 HIVE-27805: Hive server2 connections limits bug (#6168)
52b6fc322e0 is described below
commit 52b6fc322e0ab7a1a94b7a966130c9bacfa4b00f
Author: Dayakar M <[email protected]>
AuthorDate: Fri Nov 7 11:41:36 2025 +0530
HIVE-27805: Hive server2 connections limits bug (#6168)
---
.../hive/service/cli/session/SessionManager.java | 10 ++++-
.../cli/TestCLIServiceConnectionLimits.java | 48 ++++++++++++++++++++++
.../cli/session/TestSessionManagerMetrics.java | 30 ++++++++++++++
3 files changed, 87 insertions(+), 1 deletion(-)
diff --git
a/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
b/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
index 694768ae7da..274df88390e 100644
--- a/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
+++ b/service/src/java/org/apache/hive/service/cli/session/SessionManager.java
@@ -458,6 +458,7 @@ public HiveSession createSession(SessionHandle
sessionHandle, TProtocolVersion p
hiveSessionUgi = (HiveSessionImplwithUGI)
constructor.newInstance(sessionHandle,
protocol, username, password, hiveConf, ipAddress,
delegationToken, forwardedAddresses);
} catch (Exception e) {
+ decrementConnectionsCount(username, ipAddress, forwardedAddresses);
throw new HiveSQLException("Cannot initialize session class:" +
sessionImplWithUGIclassName);
}
}
@@ -475,6 +476,7 @@ public HiveSession createSession(SessionHandle
sessionHandle, TProtocolVersion p
session = (HiveSession) constructor.newInstance(sessionHandle,
protocol, username, password,
hiveConf, ipAddress, forwardedAddresses);
} catch (Exception e) {
+ decrementConnectionsCount(username, ipAddress, forwardedAddresses);
throw new HiveSQLException("Cannot initialize session class:" +
sessionImplclassName, e);
}
}
@@ -487,6 +489,7 @@ public HiveSession createSession(SessionHandle
sessionHandle, TProtocolVersion p
LOG.warn("Failed to open session", e);
try {
session.close();
+ decrementConnections(session);
} catch (Throwable t) {
LOG.warn("Error closing session", t);
}
@@ -502,6 +505,7 @@ public HiveSession createSession(SessionHandle
sessionHandle, TProtocolVersion p
LOG.warn("Failed to execute session hooks", e);
try {
session.close();
+ decrementConnections(session);
} catch (Throwable t) {
LOG.warn("Error closing session", t);
}
@@ -562,7 +566,11 @@ private String getOriginClientIpAddress(final String
ipAddress, final List<Strin
private void decrementConnections(final HiveSession session) {
final String username = session.getUserName();
- final String clientIpAddress =
getOriginClientIpAddress(session.getIpAddress(),
session.getForwardedAddresses());
+ decrementConnectionsCount(username, session.getIpAddress(),
session.getForwardedAddresses());
+ }
+
+ private void decrementConnectionsCount(String username, String ipAddress,
List<String> forwardedAddresses) {
+ final String clientIpAddress = getOriginClientIpAddress(ipAddress,
forwardedAddresses);
if (trackConnectionsPerUser(username)) {
connectionsCount.computeIfPresent(username, (k, v) -> v).decrement();
}
diff --git
a/service/src/test/org/apache/hive/service/cli/TestCLIServiceConnectionLimits.java
b/service/src/test/org/apache/hive/service/cli/TestCLIServiceConnectionLimits.java
index dff6b6e8fe1..777184dad7c 100644
---
a/service/src/test/org/apache/hive/service/cli/TestCLIServiceConnectionLimits.java
+++
b/service/src/test/org/apache/hive/service/cli/TestCLIServiceConnectionLimits.java
@@ -17,11 +17,13 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.common.IPStackUtils;
import org.apache.hive.service.cli.session.SessionManager;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -345,6 +347,52 @@ public void testConnectionForwardedIpAddresses() throws
HiveSQLException {
}
}
+ @Test
+ public void testConnectionLimitPerUserWhenSessionCreationFails() throws
HiveSQLException {
+ conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER,
2);
+
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_IPADDRESS,
0);
+
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER_IPADDRESS,
0);
+ testConnectionLimits();
+ }
+
+ @Test
+ public void testConnectionLimitPerIpAddressWhenSessionCreationFails() throws
HiveSQLException {
+ conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER,
0);
+
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_IPADDRESS,
2);
+
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER_IPADDRESS,
0);
+ testConnectionLimits();
+ }
+
+ @Test
+ public void testConnectionLimitPerUserIpAddressWhenSessionCreationFails()
throws HiveSQLException {
+ conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER,
0);
+
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_IPADDRESS,
0);
+
conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER_IPADDRESS,
2);
+ testConnectionLimits();
+ }
+
+ private void testConnectionLimits() {
+ CLIService service = getService(conf);
+ HashMap<String, String> sessionConf = new HashMap<>(1);
+ // modifying this property at runtime is not allowed, it will throw
exception and session will not be created
+ sessionConf.put("hive.conf.locked.list", "test");
+ try {
+ // Here limit is set as 2 but if session creation fails it shouldn't
increment the count and should not throw limit reached exception
+ for (int i = 0; i < 3; i++) {
+ try {
+ service.openSession(CLIService.SERVER_VERSION, "foo", "bar",
IPStackUtils.resolveLoopbackAddress(),
+ sessionConf);
+ } catch (HiveSQLException he) {
+ Assert.assertEquals(
+ "Failed to open new session: Cannot modify hive.conf.locked.list
at runtime. It is in the list of parameters that can't be modified at runtime
or is prefixed by a restricted variable",
+ he.getMessage());
+ }
+ }
+ } finally {
+ service.stop();
+ }
+ }
+
private CLIService getService(HiveConf conf) {
conf.setVar(HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER,
"org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory");
diff --git
a/service/src/test/org/apache/hive/service/cli/session/TestSessionManagerMetrics.java
b/service/src/test/org/apache/hive/service/cli/session/TestSessionManagerMetrics.java
index 9ed2a15e9a2..e227ff45e76 100644
---
a/service/src/test/org/apache/hive/service/cli/session/TestSessionManagerMetrics.java
+++
b/service/src/test/org/apache/hive/service/cli/session/TestSessionManagerMetrics.java
@@ -80,6 +80,7 @@ public void setup() throws Exception {
//it maybe impact TestSessionCleanup, because they use the same location
ConfVars.HIVE_SERVER2_LOGGING_OPERATION_LOG_LOCATION,
// when we run testing in parallel on local machine with -DforkCount=x, it
happen.
conf.setBoolVar(HiveConf.ConfVars.HIVE_SERVER2_LOGGING_OPERATION_ENABLED,
false);
+ conf.setIntVar(HiveConf.ConfVars.HIVE_SERVER2_LIMIT_CONNECTIONS_PER_USER,
2);
MetricsFactory.init(conf);
sm = new SessionManager(null, true);
@@ -396,4 +397,33 @@ public void testAbandonedSessionMetrics() throws Exception
{
} while (!expectedValue.equals(currentValue) && --count > 0);
Assert.assertEquals(expectedValue, currentValue);
}
+
+ @Test
+ public void testSessionLimitsPerUserWhenSessionCreationFails() throws
Exception {
+ sm.start();
+ HashMap<String, String> sessionConf = new HashMap<>(1);
+ // modifying this property at runtime is not allowed, it will throw
exception and session will not be created
+ sessionConf.put("hive.conf.locked.list", "test");
+ for (int i = 0; i < 3; i++) {
+ try {
+ sm.openSession(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V9, "user",
"passw", "127.0.0.1", sessionConf);
+ } catch (HiveSQLException e) {
+ // Here 'hive.server2.limit.connections.per.user' property value set
as 2 so when we create 3 sessions, for all 3 sessions it should throw exception
with failure reason
+ // It should not throw exception with 'Connection limit per user
reached (user: user limit: 2)' message
+ Assert.assertEquals(
+ "Failed to open new session: Cannot modify hive.conf.locked.list
at runtime. It is in the list of parameters that can't be modified at runtime
or is prefixed by a restricted variable",
+ e.getMessage());
+ }
+ }
+ SessionHandle handle = null;
+ // After 3 unsuccessful session creations now session creation with proper
details should be able to create the session
+ try {
+ handle = sm.openSession(TProtocolVersion.HIVE_CLI_SERVICE_PROTOCOL_V9,
"user", "passw", "127.0.0.1",
+ new HashMap<String, String>());
+ } finally {
+ if (null != handle) {
+ sm.closeSession(handle);
+ }
+ }
+ }
}