This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.1 by this push:
new 47fa76e0f6b [2.1][fix](jdbc catalog) Optimize JDBC Connection Closing
to Ensure Proper Resource Release (#43074)
47fa76e0f6b is described below
commit 47fa76e0f6b0522d87c7da04a86506fd42240566
Author: zy-kkk <[email protected]>
AuthorDate: Fri Nov 1 20:34:18 2024 +0800
[2.1][fix](jdbc catalog) Optimize JDBC Connection Closing to Ensure Proper
Resource Release (#43074)
bp #43059
---
.../org/apache/doris/jdbc/BaseJdbcExecutor.java | 14 ++++--
.../doris/datasource/jdbc/client/JdbcClient.java | 54 ++++++++++++++--------
.../datasource/jdbc/client/JdbcDB2Client.java | 3 +-
.../datasource/jdbc/client/JdbcGbaseClient.java | 6 ++-
.../datasource/jdbc/client/JdbcMySQLClient.java | 21 +++++----
.../datasource/jdbc/client/JdbcOracleClient.java | 3 +-
6 files changed, 67 insertions(+), 34 deletions(-)
diff --git
a/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java
b/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java
index 79122fc1217..3a7342d6280 100644
---
a/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java
+++
b/fe/be-java-extensions/jdbc-scanner/src/main/java/org/apache/doris/jdbc/BaseJdbcExecutor.java
@@ -124,11 +124,17 @@ public abstract class BaseJdbcExecutor implements
JdbcExecutor {
}
}
- private void closeResources(AutoCloseable... closeables) {
- for (AutoCloseable closeable : closeables) {
- if (closeable != null) {
+ private void closeResources(Object... resources) {
+ for (Object resource : resources) {
+ if (resource != null) {
try {
- closeable.close();
+ if (resource instanceof ResultSet) {
+ ((ResultSet) resource).close();
+ } else if (resource instanceof Statement) {
+ ((Statement) resource).close();
+ } else if (resource instanceof Connection) {
+ ((Connection) resource).close();
+ }
} catch (Exception e) {
LOG.warn("Cannot close resource: ", e);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
index 80a858e86a8..54f15f7404e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcClient.java
@@ -136,6 +136,7 @@ public abstract class JdbcClient {
dataSource.setConnectionTimeout(config.getConnectionPoolMaxWaitTime()); //
default 5000
dataSource.setMaxLifetime(config.getConnectionPoolMaxLifeTime());
// default 30 min
dataSource.setIdleTimeout(config.getConnectionPoolMaxLifeTime() /
2L); // default 15 min
+ dataSource.setConnectionTestQuery(getTestQuery());
LOG.info("JdbcClient set"
+ " ConnectionPoolMinSize = " +
config.getConnectionPoolMinSize()
+ ", ConnectionPoolMaxSize = " +
config.getConnectionPoolMaxSize()
@@ -187,13 +188,19 @@ public abstract class JdbcClient {
return conn;
}
- public void close(AutoCloseable... closeables) {
- for (AutoCloseable closeable : closeables) {
- if (closeable != null) {
+ public void close(Object... resources) {
+ for (Object resource : resources) {
+ if (resource != null) {
try {
- closeable.close();
- } catch (Exception e) {
- throw new JdbcClientException("Can not close : ", e);
+ if (resource instanceof ResultSet) {
+ ((ResultSet) resource).close();
+ } else if (resource instanceof Statement) {
+ ((Statement) resource).close();
+ } else if (resource instanceof Connection) {
+ ((Connection) resource).close();
+ }
+ } catch (SQLException e) {
+ LOG.warn("Failed to close resource: {}", e.getMessage(),
e);
}
}
}
@@ -205,9 +212,10 @@ public abstract class JdbcClient {
* @param origStmt, the raw stmt string
*/
public void executeStmt(String origStmt) {
- Connection conn = getConnection();
+ Connection conn = null;
Statement stmt = null;
try {
+ conn = getConnection();
stmt = conn.createStatement();
int effectedRows = stmt.executeUpdate(origStmt);
if (LOG.isDebugEnabled()) {
@@ -227,10 +235,12 @@ public abstract class JdbcClient {
* @return List<Column>
*/
public List<Column> getColumnsFromQuery(String query) {
- Connection conn = getConnection();
+ Connection conn = null;
+ PreparedStatement pstmt = null;
List<Column> columns = Lists.newArrayList();
try {
- PreparedStatement pstmt = conn.prepareStatement(query);
+ conn = getConnection();
+ pstmt = conn.prepareStatement(query);
ResultSetMetaData metaData = pstmt.getMetaData();
if (metaData == null) {
throw new JdbcClientException("Query not supported: Failed to
get ResultSetMetaData from query: %s",
@@ -245,12 +255,11 @@ public abstract class JdbcClient {
} catch (SQLException e) {
throw new JdbcClientException("Failed to get columns from query:
%s", e, query);
} finally {
- close(conn);
+ close(pstmt, conn);
}
return columns;
}
-
/**
* Get schema from ResultSetMetaData
*
@@ -273,10 +282,11 @@ public abstract class JdbcClient {
* @return list of database names
*/
public List<String> getDatabaseNameList() {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
List<String> remoteDatabaseNames = Lists.newArrayList();
try {
+ conn = getConnection();
if (isOnlySpecifiedDatabase && includeDatabaseMap.isEmpty() &&
excludeDatabaseMap.isEmpty()) {
String currentDatabase = conn.getSchema();
remoteDatabaseNames.add(currentDatabase);
@@ -335,12 +345,13 @@ public abstract class JdbcClient {
* get all columns of one table
*/
public List<JdbcFieldSchema> getJdbcColumnsInfo(String localDbName, String
localTableName) {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
List<JdbcFieldSchema> tableSchema = Lists.newArrayList();
String remoteDbName = getRemoteDatabaseName(localDbName);
String remoteTableName = getRemoteTableName(localDbName,
localTableName);
try {
+ conn = getConnection();
DatabaseMetaData databaseMetaData = conn.getMetaData();
String catalogName = getCatalogName(conn);
rs = getRemoteColumns(databaseMetaData, catalogName, remoteDbName,
remoteTableName);
@@ -382,7 +393,7 @@ public abstract class JdbcClient {
return jdbcLowerCaseMetaMatching.getRemoteColumnNames(localDbName,
localTableName);
}
- // protected methods,for subclass to override
+ // protected methods, for subclass to override
protected String getCatalogName(Connection conn) throws SQLException {
return conn.getCatalog();
}
@@ -393,9 +404,10 @@ public abstract class JdbcClient {
protected void processTable(String remoteDbName, String remoteTableName,
String[] tableTypes,
Consumer<ResultSet> resultSetConsumer) {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
try {
+ conn = getConnection();
DatabaseMetaData databaseMetaData = conn.getMetaData();
String catalogName = getCatalogName(conn);
rs = databaseMetaData.getTables(catalogName, remoteDbName,
remoteTableName, tableTypes);
@@ -467,15 +479,21 @@ public abstract class JdbcClient {
public void testConnection() {
String testQuery = getTestQuery();
- try (Connection conn = getConnection();
- Statement stmt = conn.createStatement();
- ResultSet rs = stmt.executeQuery(testQuery)) {
+ Connection conn = null;
+ Statement stmt = null;
+ ResultSet rs = null;
+ try {
+ conn = getConnection();
+ stmt = conn.createStatement();
+ rs = stmt.executeQuery(testQuery);
if (!rs.next()) {
throw new JdbcClientException(
"Failed to test connection in FE: query executed but
returned no results.");
}
} catch (SQLException e) {
throw new JdbcClientException("Failed to test connection in FE: "
+ e.getMessage(), e);
+ } finally {
+ close(rs, stmt, conn);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcDB2Client.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcDB2Client.java
index dafb00ca9e8..a353b7ac361 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcDB2Client.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcDB2Client.java
@@ -41,10 +41,11 @@ public class JdbcDB2Client extends JdbcClient {
@Override
public List<String> getDatabaseNameList() {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
List<String> remoteDatabaseNames = Lists.newArrayList();
try {
+ conn = getConnection();
if (isOnlySpecifiedDatabase && includeDatabaseMap.isEmpty() &&
excludeDatabaseMap.isEmpty()) {
String currentDatabase = conn.getSchema().trim();
remoteDatabaseNames.add(currentDatabase);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcGbaseClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcGbaseClient.java
index 5aaacb3e673..7ba393e0d0a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcGbaseClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcGbaseClient.java
@@ -41,10 +41,11 @@ public class JdbcGbaseClient extends JdbcClient {
@Override
public List<String> getDatabaseNameList() {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
List<String> remoteDatabaseNames = Lists.newArrayList();
try {
+ conn = getConnection();
if (isOnlySpecifiedDatabase && includeDatabaseMap.isEmpty() &&
excludeDatabaseMap.isEmpty()) {
String currentDatabase = conn.getCatalog();
remoteDatabaseNames.add(currentDatabase);
@@ -87,12 +88,13 @@ public class JdbcGbaseClient extends JdbcClient {
@Override
public List<JdbcFieldSchema> getJdbcColumnsInfo(String localDbName, String
localTableName) {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
List<JdbcFieldSchema> tableSchema = Lists.newArrayList();
String remoteDbName = getRemoteDatabaseName(localDbName);
String remoteTableName = getRemoteTableName(localDbName,
localTableName);
try {
+ conn = getConnection();
DatabaseMetaData databaseMetaData = conn.getMetaData();
String catalogName = getCatalogName(conn);
rs = getRemoteColumns(databaseMetaData, catalogName, remoteDbName,
remoteTableName);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
index 465a3c152ac..a8263f1621a 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcMySQLClient.java
@@ -76,10 +76,11 @@ public class JdbcMySQLClient extends JdbcClient {
@Override
public List<String> getDatabaseNameList() {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
List<String> remoteDatabaseNames = Lists.newArrayList();
try {
+ conn = getConnection();
if (isOnlySpecifiedDatabase && includeDatabaseMap.isEmpty() &&
excludeDatabaseMap.isEmpty()) {
String currentDatabase = conn.getCatalog();
remoteDatabaseNames.add(currentDatabase);
@@ -130,12 +131,13 @@ public class JdbcMySQLClient extends JdbcClient {
*/
@Override
public List<JdbcFieldSchema> getJdbcColumnsInfo(String localDbName, String
localTableName) {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
List<JdbcFieldSchema> tableSchema = Lists.newArrayList();
String remoteDbName = getRemoteDatabaseName(localDbName);
String remoteTableName = getRemoteTableName(localDbName,
localTableName);
try {
+ conn = getConnection();
DatabaseMetaData databaseMetaData = conn.getMetaData();
String catalogName = getCatalogName(conn);
rs = getRemoteColumns(databaseMetaData, catalogName, remoteDbName,
remoteTableName);
@@ -294,30 +296,33 @@ public class JdbcMySQLClient extends JdbcClient {
* get all columns like DatabaseMetaData.getColumns in mysql-jdbc-connector
*/
private Map<String, String> getColumnsDataTypeUseQuery(String
remoteDbName, String remoteTableName) {
- Connection conn = getConnection();
+ Connection conn = null;
+ Statement stmt = null;
ResultSet resultSet = null;
- Map<String, String> fieldtoType = Maps.newHashMap();
+ Map<String, String> fieldToType = Maps.newHashMap();
StringBuilder queryBuf = new StringBuilder("SHOW FULL COLUMNS FROM ");
queryBuf.append(remoteTableName);
queryBuf.append(" FROM ");
queryBuf.append(remoteDbName);
- try (Statement stmt = conn.createStatement()) {
+ try {
+ conn = getConnection();
+ stmt = conn.createStatement();
resultSet = stmt.executeQuery(queryBuf.toString());
while (resultSet.next()) {
// get column name
String fieldName = resultSet.getString("Field");
// get original type name
String typeName = resultSet.getString("Type");
- fieldtoType.put(fieldName, typeName);
+ fieldToType.put(fieldName, typeName);
}
} catch (SQLException e) {
throw new JdbcClientException("failed to get jdbc columns info for
remote table `%s.%s`: %s",
remoteDbName, remoteTableName,
Util.getRootCauseMessage(e));
} finally {
- close(resultSet, conn);
+ close(resultSet, stmt, conn);
}
- return fieldtoType;
+ return fieldToType;
}
private Type dorisTypeToDoris(JdbcFieldSchema fieldSchema) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcOracleClient.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcOracleClient.java
index d37b36cbf3d..9968de79ab3 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcOracleClient.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/client/JdbcOracleClient.java
@@ -50,12 +50,13 @@ public class JdbcOracleClient extends JdbcClient {
@Override
public List<JdbcFieldSchema> getJdbcColumnsInfo(String localDbName, String
localTableName) {
- Connection conn = getConnection();
+ Connection conn = null;
ResultSet rs = null;
List<JdbcFieldSchema> tableSchema = Lists.newArrayList();
String remoteDbName = getRemoteDatabaseName(localDbName);
String remoteTableName = getRemoteTableName(localDbName,
localTableName);
try {
+ conn = getConnection();
DatabaseMetaData databaseMetaData = conn.getMetaData();
String catalogName = getCatalogName(conn);
String modifiedTableName;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]