This is an automated email from the ASF dual-hosted git repository.

dengzh 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 18f34e75da0 HIVE-28460: Determine the database type once the 
PersistenceManagerFactory created (#5474) (Zhihua Deng, reviewed by Dmitriy 
Fingerman, Denys Kuzmenko)
18f34e75da0 is described below

commit 18f34e75da0141d37d9a8f1cef4f7f64ba09fadb
Author: dengzh <[email protected]>
AuthorDate: Tue Nov 5 09:17:15 2024 +0800

    HIVE-28460: Determine the database type once the PersistenceManagerFactory 
created (#5474) (Zhihua Deng, reviewed by Dmitriy Fingerman, Denys Kuzmenko)
---
 .../hadoop/hive/metastore/DatabaseProduct.java     | 19 +++++++++++++
 .../hadoop/hive/metastore/MetaStoreDirectSql.java  | 23 +--------------
 .../apache/hadoop/hive/metastore/ObjectStore.java  | 23 ++-------------
 .../hive/metastore/PersistenceManagerProvider.java | 33 ++++++++++++++++++++--
 .../hadoop/hive/metastore/txn/TxnHandler.java      | 25 +++-------------
 5 files changed, 56 insertions(+), 67 deletions(-)

diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java
index 7a5f2059589..2b012b9a9bb 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java
@@ -18,6 +18,7 @@
 
 package org.apache.hadoop.hive.metastore;
 
+import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.SQLIntegrityConstraintViolationException;
 import java.sql.SQLTransactionRollbackException;
@@ -44,6 +45,8 @@ import org.slf4j.LoggerFactory;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 
+import javax.sql.DataSource;
+
 /** Database product inferred via JDBC. Encapsulates all SQL logic associated 
with
  * the database product.
  * This class is a singleton, which is instantiated the first time
@@ -70,6 +73,8 @@ public class DatabaseProduct implements Configurable {
   private static DatabaseProduct theDatabaseProduct;
 
   Configuration myConf;
+
+  private String productName;
   /**
    * Protected constructor for singleton class
    */
@@ -83,6 +88,16 @@ public class DatabaseProduct implements Configurable {
   public static final String ORACLE_NAME = "oracle";
   public static final String UNDEFINED_NAME = "other";
 
+  public static DatabaseProduct determineDatabaseProduct(DataSource connPool,
+      Configuration conf) {
+    try (Connection conn = connPool.getConnection()) {
+      String s = conn.getMetaData().getDatabaseProductName();
+      return determineDatabaseProduct(s, conf);
+    } catch (SQLException e) {
+      throw new IllegalStateException("Unable to get database product name", 
e);
+    }
+  }
+
   /**
    * Determine the database product type
    * @param productName string to defer database connection
@@ -144,6 +159,7 @@ public class DatabaseProduct implements Configurable {
         }
 
         theDatabaseProduct.dbType = dbt;
+        theDatabaseProduct.productName = productName;
       }
     }
     return theDatabaseProduct;
@@ -817,4 +833,7 @@ public class DatabaseProduct implements Configurable {
     return dbType == DbType.DERBY || dbType == DbType.ORACLE;
   }
 
+  public String getProductName() {
+    return productName;
+  }
 }
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java
index 35079df61d3..a1ada03b7c2 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java
@@ -193,11 +193,7 @@ class MetaStoreDirectSql {
     this.pm = pm;
     this.conf = conf;
     this.schema = schema;
-    DatabaseProduct dbType = null;
-
-    dbType = DatabaseProduct.determineDatabaseProduct(getProductName(pm), 
conf);
-
-    this.dbType = dbType;
+    this.dbType = PersistenceManagerProvider.getDatabaseProduct();
     int batchSize = MetastoreConf.getIntVar(conf, 
ConfVars.DIRECT_SQL_PARTITION_BATCH_SIZE);
     this.directSqlInsertPart = new DirectSqlInsertPart(pm, dbType, batchSize);
     if (batchSize == DETECT_BATCHING) {
@@ -272,23 +268,6 @@ class MetaStoreDirectSql {
         + "\"" + tblName + "\"";
   }
 
-
-  public MetaStoreDirectSql(PersistenceManager pm, Configuration conf) {
-    this(pm, conf, "");
-  }
-
-  static String getProductName(PersistenceManager pm) {
-    JDOConnection jdoConn = pm.getDataStoreConnection();
-    try {
-      return 
((Connection)jdoConn.getNativeConnection()).getMetaData().getDatabaseProductName();
-    } catch (Throwable t) {
-      LOG.warn("Error retrieving product name", t);
-      return null;
-    } finally {
-      jdoConn.close(); // We must release the connection before we call other 
pm methods.
-    }
-  }
-
   private boolean ensureDbInit() {
     Transaction tx = pm.currentTransaction();
     boolean doCommit = false;
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
index c41d4d0087e..314f78fd1d5 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
@@ -434,12 +434,10 @@ public class ObjectStore implements RawStore, 
Configurable {
     LOG.info("RawStore: {}, with PersistenceManager: {}" +
         " created in the thread with id: {}", this, pm, 
Thread.currentThread().getId());
 
-    String productName = MetaStoreDirectSql.getProductName(pm);
-    sqlGenerator = new 
SQLGenerator(DatabaseProduct.determineDatabaseProduct(productName, conf), conf);
-
     isInitialized = pm != null;
     if (isInitialized) {
-      dbType = determineDatabaseProduct();
+      dbType = PersistenceManagerProvider.getDatabaseProduct();
+      sqlGenerator = new SQLGenerator(dbType, conf);
       expressionProxy = PartFilterExprUtil.createExpressionProxy(conf);
       if (MetastoreConf.getBoolVar(getConf(), ConfVars.TRY_DIRECT_SQL)) {
         String schema = 
PersistenceManagerProvider.getProperty("javax.jdo.mapping.Schema");
@@ -460,22 +458,6 @@ public class ObjectStore implements RawStore, Configurable 
{
     return propertyStore;
   }
 
-  private DatabaseProduct determineDatabaseProduct() {
-      return DatabaseProduct.determineDatabaseProduct(getProductName(pm), 
conf);
-  }
-
-  private static String getProductName(PersistenceManager pm) {
-    JDOConnection jdoConn = pm.getDataStoreConnection();
-    try {
-      return 
((Connection)jdoConn.getNativeConnection()).getMetaData().getDatabaseProductName();
-    } catch (Throwable t) {
-      LOG.warn("Error retrieving product name", t);
-      return null;
-    } finally {
-      jdoConn.close(); // We must release the connection before we call other 
pm methods.
-    }
-  }
-
   /**
    * Configure SSL encryption to the database store.
    *
@@ -4449,7 +4431,6 @@ public class ObjectStore implements RawStore, 
Configurable {
       boolean isConfigEnabled = MetastoreConf.getBoolVar(getConf(), 
ConfVars.TRY_DIRECT_SQL)
           && (MetastoreConf.getBoolVar(getConf(), ConfVars.TRY_DIRECT_SQL_DDL) 
|| !isInTxn);
       if (isConfigEnabled && directSql == null) {
-        dbType = determineDatabaseProduct();
         directSql = new MetaStoreDirectSql(pm, getConf(), "");
       }
 
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PersistenceManagerProvider.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PersistenceManagerProvider.java
index 723ece51a36..9afc7168aaa 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PersistenceManagerProvider.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PersistenceManagerProvider.java
@@ -83,6 +83,7 @@ import static 
org.apache.hadoop.hive.metastore.conf.MetastoreConf.ConfVars.COMPA
 public class PersistenceManagerProvider {
   private static PersistenceManagerFactory pmf;
   private static PersistenceManagerFactory compactorPmf;
+  private static DatabaseProduct databaseProduct;
   private static Properties prop;
   private static final ReentrantReadWriteLock pmfLock = new 
ReentrantReadWriteLock();
   private static final Lock pmfReadLock = pmfLock.readLock();
@@ -271,6 +272,10 @@ public class PersistenceManagerProvider {
             if (compactorPmf == null && useCompactorPool) {
               compactorPmf = retry(() -> initPMF(conf, true));
             }
+            if (databaseProduct == null) {
+              String url = MetastoreConf.getVar(conf, 
MetastoreConf.ConfVars.CONNECT_URL_KEY);
+              databaseProduct = DatabaseProduct.determineDatabaseProduct(url, 
conf);
+            }
           }
           // downgrade by acquiring read lock before releasing write lock
           pmfReadLock.lock();
@@ -288,7 +293,7 @@ public class PersistenceManagerProvider {
 
   private static PersistenceManagerFactory initPMF(Configuration conf, boolean 
forCompactor) {
     DataSourceProvider dsp = 
DataSourceProviderFactory.tryGetDataSourceProviderOrNull(conf);
-    PersistenceManagerFactory pmf;
+    PersistenceManagerFactory pmf = null;
 
     // Any preexisting datanucleus property should be passed along
     Map<Object, Object> dsProp = new HashMap<>(prop);
@@ -301,15 +306,18 @@ public class PersistenceManagerProvider {
     if (dsp == null) {
       pmf = JDOHelper.getPersistenceManagerFactory(dsProp);
     } else {
+      DataSource ds = null;
+      DataSource ds2 = null;
       String sourceName = forCompactor ? "objectstore-compactor" : 
"objectstore";
       try (DataSourceProvider.DataSourceNameConfigurator configurator =
                new DataSourceProvider.DataSourceNameConfigurator(conf, 
sourceName)) {
-        DataSource ds = (maxPoolSize > 0) ? dsp.create(conf, maxPoolSize) : 
dsp.create(conf);
+        ds = (maxPoolSize > 0) ? dsp.create(conf, maxPoolSize) : 
dsp.create(conf);
+        databaseProduct = DatabaseProduct.determineDatabaseProduct(ds, conf);
         // The secondary connection factory is used for schema generation, and 
for value generation operations.
         // We should use a different pool for the secondary connection factory 
to avoid resource starvation.
         // Since DataNucleus uses locks for schema generation and value 
generation, 2 connections should be sufficient.
         configurator.resetName(sourceName + "-secondary");
-        DataSource ds2 = dsp.create(conf, /* maxPoolSize */ 2);
+        ds2 = dsp.create(conf, /* maxPoolSize */ 2);
         dsProp.put(PropertyNames.PROPERTY_CONNECTION_FACTORY, ds);
         dsProp.put(PropertyNames.PROPERTY_CONNECTION_FACTORY2, ds2);
         dsProp.put(ConfVars.MANAGER_FACTORY_CLASS.getVarname(),
@@ -319,8 +327,18 @@ public class PersistenceManagerProvider {
         LOG.warn("Could not create PersistenceManagerFactory using "
             + "connection pool properties, will fall back", e);
         pmf = JDOHelper.getPersistenceManagerFactory(prop);
+      } finally {
+        if (pmf == null && ds instanceof AutoCloseable) {
+          try (AutoCloseable close1 = (AutoCloseable) ds;
+               AutoCloseable close2 = (AutoCloseable) ds2 ) {
+            LOG.debug("Trying to close the dangling datasource as the pmf is 
null");
+          } catch (Exception e) {
+            LOG.warn("Failed to close the DataSource", e);
+          }
+        }
       }
     }
+    assert pmf != null;
     DataStoreCache dsc = pmf.getDataStoreCache();
     if (dsc != null) {
       String objTypes = MetastoreConf.getVar(conf, ConfVars.CACHE_PINOBJTYPES);
@@ -499,6 +517,14 @@ public class PersistenceManagerProvider {
     }
   }
 
+  public static DatabaseProduct getDatabaseProduct() {
+    if (databaseProduct == null) {
+      throw new IllegalStateException(
+          "Cannot determine the database product. PersistenceManagerFactory 
has not been initialized yet");
+    }
+    return databaseProduct;
+  }
+
   /**
    * Properties specified in hive-default.xml override the properties specified
    * in jpox.properties.
@@ -625,6 +651,7 @@ public class PersistenceManagerProvider {
             LOG.warn("Exception retry limit reached, not retrying any 
longer.", e);
           } else {
             LOG.debug("Non-retriable exception.", e);
+            break;
           }
           ex = e;
         }
diff --git 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnHandler.java
 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnHandler.java
index f9283364546..6e002da6ad9 100644
--- 
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnHandler.java
+++ 
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/TxnHandler.java
@@ -292,11 +292,10 @@ public abstract class TxnHandler implements TxnStore, 
TxnStore.MutexAPI {
             }
           }
           if (dbProduct == null) {
-            try (Connection dbConn = 
getDbConn(Connection.TRANSACTION_READ_COMMITTED, connPool)) {
-              determineDatabaseProduct(dbConn);
-            } catch (SQLException e) {
-              LOG.error("Unable to determine database product", e);
-              throw new RuntimeException(e);
+            dbProduct = DatabaseProduct.determineDatabaseProduct(connPool, 
conf);
+            if (dbProduct.isUNDEFINED()) {
+              String msg = "Unrecognized database product name <" + 
dbProduct.getProductName() + ">";
+              throw new IllegalStateException(msg);
             }
           }
           if (sqlGenerator == null) {
@@ -1065,22 +1064,6 @@ public abstract class TxnHandler implements TxnStore, 
TxnStore.MutexAPI {
         (ResultSet rs, int rowNum) -> rs.getTimestamp(1));
   }
 
-  private void determineDatabaseProduct(Connection conn) {
-    try {
-      String s = conn.getMetaData().getDatabaseProductName();
-      dbProduct = DatabaseProduct.determineDatabaseProduct(s, conf);
-      if (dbProduct.isUNDEFINED()) {
-        String msg = "Unrecognized database product name <" + s + ">";
-        LOG.error(msg);
-        throw new IllegalStateException(msg);
-      }
-    } catch (SQLException e) {
-      String msg = "Unable to get database product name";
-      LOG.error(msg, e);
-      throw new IllegalStateException(msg, e);
-    }
-  }
-  
   private void initJdbcResource() {
     if (jdbcResource == null) {
       jdbcResource = new MultiDataSourceJdbcResource(dbProduct, conf, 
sqlGenerator);

Reply via email to