You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by bl...@apache.org on 2021/10/28 22:03:59 UTC

[iceberg] branch master updated: Hive: Limit number of retries when metadata file is missing (#3379)

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

blue pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iceberg.git


The following commit(s) were added to refs/heads/master by this push:
     new fa9bb09  Hive: Limit number of retries when metadata file is missing (#3379)
fa9bb09 is described below

commit fa9bb09055faadf37a0e547b6c1bdd4a8bac0be3
Author: Kevin Liu <80...@users.noreply.github.com>
AuthorDate: Thu Oct 28 15:03:51 2021 -0700

    Hive: Limit number of retries when metadata file is missing (#3379)
    
    Co-authored-by: Kevin Liu <ke...@gmail.com>
---
 .../org/apache/iceberg/hive/HiveTableOperations.java    |  7 ++++++-
 .../java/org/apache/iceberg/hive/HiveTableBaseTest.java |  2 +-
 .../java/org/apache/iceberg/hive/HiveTableTest.java     | 17 +++++++++++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveTableOperations.java b/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveTableOperations.java
index e975c92..5af7f33 100644
--- a/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveTableOperations.java
+++ b/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveTableOperations.java
@@ -86,10 +86,12 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
   private static final String HIVE_ACQUIRE_LOCK_TIMEOUT_MS = "iceberg.hive.lock-timeout-ms";
   private static final String HIVE_LOCK_CHECK_MIN_WAIT_MS = "iceberg.hive.lock-check-min-wait-ms";
   private static final String HIVE_LOCK_CHECK_MAX_WAIT_MS = "iceberg.hive.lock-check-max-wait-ms";
+  private static final String HIVE_ICEBERG_METADATA_REFRESH_MAX_RETRIES = "iceberg.hive.metadata-refresh-max-retries";
   private static final String HIVE_TABLE_LEVEL_LOCK_EVICT_MS = "iceberg.hive.table-level-lock-evict-ms";
   private static final long HIVE_ACQUIRE_LOCK_TIMEOUT_MS_DEFAULT = 3 * 60 * 1000; // 3 minutes
   private static final long HIVE_LOCK_CHECK_MIN_WAIT_MS_DEFAULT = 50; // 50 milliseconds
   private static final long HIVE_LOCK_CHECK_MAX_WAIT_MS_DEFAULT = 5 * 1000; // 5 seconds
+  private static final int HIVE_ICEBERG_METADATA_REFRESH_MAX_RETRIES_DEFAULT = 2;
   private static final long HIVE_TABLE_LEVEL_LOCK_EVICT_MS_DEFAULT = TimeUnit.MINUTES.toMillis(10);
   private static final DynMethods.UnboundMethod ALTER_TABLE = DynMethods.builder("alter_table")
       .impl(IMetaStoreClient.class, "alter_table_with_environmentContext",
@@ -144,6 +146,7 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
   private final long lockAcquireTimeout;
   private final long lockCheckMinWaitTime;
   private final long lockCheckMaxWaitTime;
+  private final int metadataRefreshMaxRetries;
   private final FileIO fileIO;
   private final ClientPool<IMetaStoreClient, TException> metaClients;
 
@@ -161,6 +164,8 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
         conf.getLong(HIVE_LOCK_CHECK_MIN_WAIT_MS, HIVE_LOCK_CHECK_MIN_WAIT_MS_DEFAULT);
     this.lockCheckMaxWaitTime =
         conf.getLong(HIVE_LOCK_CHECK_MAX_WAIT_MS, HIVE_LOCK_CHECK_MAX_WAIT_MS_DEFAULT);
+    this.metadataRefreshMaxRetries =
+        conf.getInt(HIVE_ICEBERG_METADATA_REFRESH_MAX_RETRIES, HIVE_ICEBERG_METADATA_REFRESH_MAX_RETRIES_DEFAULT);
     long tableLevelLockCacheEvictionTimeout =
         conf.getLong(HIVE_TABLE_LEVEL_LOCK_EVICT_MS, HIVE_TABLE_LEVEL_LOCK_EVICT_MS_DEFAULT);
     initTableLevelLockCache(tableLevelLockCacheEvictionTimeout);
@@ -199,7 +204,7 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
       throw new RuntimeException("Interrupted during refresh", e);
     }
 
-    refreshFromMetadataLocation(metadataLocation);
+    refreshFromMetadataLocation(metadataLocation, metadataRefreshMaxRetries);
   }
 
   @SuppressWarnings("checkstyle:CyclomaticComplexity")
diff --git a/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableBaseTest.java b/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableBaseTest.java
index 76f2192..b584b9e 100644
--- a/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableBaseTest.java
+++ b/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableBaseTest.java
@@ -79,7 +79,7 @@ public class HiveTableBaseTest extends HiveMetastoreTest {
     return getTableLocationPath(tableName).toString();
   }
 
-  private static String metadataLocation(String tableName) {
+  protected static String metadataLocation(String tableName) {
     return Paths.get(getTableBasePath(tableName), "metadata").toString();
   }
 
diff --git a/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableTest.java b/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableTest.java
index 973780a..4012a48 100644
--- a/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableTest.java
+++ b/hive-metastore/src/test/java/org/apache/iceberg/hive/HiveTableTest.java
@@ -34,6 +34,7 @@ import org.apache.hadoop.hive.metastore.api.SerDeInfo;
 import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
 import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants;
 import org.apache.hadoop.hive.serde.serdeConstants;
+import org.apache.iceberg.AssertHelpers;
 import org.apache.iceberg.DataFile;
 import org.apache.iceberg.DataFiles;
 import org.apache.iceberg.Files;
@@ -48,6 +49,7 @@ import org.apache.iceberg.avro.AvroSchemaUtil;
 import org.apache.iceberg.catalog.Namespace;
 import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.iceberg.exceptions.CommitFailedException;
+import org.apache.iceberg.exceptions.NotFoundException;
 import org.apache.iceberg.hadoop.ConfigProperties;
 import org.apache.iceberg.io.FileAppender;
 import org.apache.iceberg.relocated.com.google.common.collect.Lists;
@@ -434,6 +436,21 @@ public class HiveTableTest extends HiveTableBaseTest {
     assertHiveEnabled(hmsTable, false);
   }
 
+  @Test
+  public void testMissingMetadataWontCauseHang() {
+    catalog.loadTable(TABLE_IDENTIFIER);
+
+    File realLocation = new File(metadataLocation(TABLE_NAME));
+    File fakeLocation = new File(metadataLocation(TABLE_NAME) + "_dummy");
+
+    Assert.assertTrue(realLocation.renameTo(fakeLocation));
+    AssertHelpers.assertThrows(
+            "HiveTableOperations shouldn't hang indefinitely when a missing metadata file is encountered",
+            NotFoundException.class,
+            () -> catalog.loadTable(TABLE_IDENTIFIER));
+    Assert.assertTrue(fakeLocation.renameTo(realLocation));
+  }
+
   private void assertHiveEnabled(org.apache.hadoop.hive.metastore.api.Table hmsTable, boolean expected) {
     if (expected) {
       Assert.assertEquals("org.apache.iceberg.mr.hive.HiveIcebergStorageHandler",