You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iceberg.apache.org by pv...@apache.org on 2023/04/25 07:13:26 UTC
[iceberg] branch master updated: Hive: Use EnvironmentContext instead of Hive Locks to provide transactional commits after HIVE-26882 (#6570)
This is an automated email from the ASF dual-hosted git repository.
pvary 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 c3232b6647 Hive: Use EnvironmentContext instead of Hive Locks to provide transactional commits after HIVE-26882 (#6570)
c3232b6647 is described below
commit c3232b664745ebf761b6a74f4c5b55cc48bfd209
Author: pvary <pe...@gmail.com>
AuthorDate: Tue Apr 25 09:13:20 2023 +0200
Hive: Use EnvironmentContext instead of Hive Locks to provide transactional commits after HIVE-26882 (#6570)
---
.../java/org/apache/iceberg/TableProperties.java | 3 +
.../apache/iceberg/hadoop/ConfigProperties.java | 1 +
docs/configuration.md | 13 +++++
.../apache/iceberg/hive/HiveTableOperations.java | 66 +++++++++++++++++++--
.../org/apache/iceberg/hive/MetastoreUtil.java | 28 +++++++--
.../main/java/org/apache/iceberg/hive/NoLock.java | 27 +++++++--
.../apache/iceberg/hive/TestHiveCommitLocks.java | 41 +++++++++++++
.../org/apache/iceberg/hive/TestHiveCommits.java | 67 ++++++++++++++++++----
8 files changed, 217 insertions(+), 29 deletions(-)
diff --git a/core/src/main/java/org/apache/iceberg/TableProperties.java b/core/src/main/java/org/apache/iceberg/TableProperties.java
index 4a1b6678b8..b14354def6 100644
--- a/core/src/main/java/org/apache/iceberg/TableProperties.java
+++ b/core/src/main/java/org/apache/iceberg/TableProperties.java
@@ -303,6 +303,9 @@ public class TableProperties {
public static final String ENGINE_HIVE_ENABLED = "engine.hive.enabled";
public static final boolean ENGINE_HIVE_ENABLED_DEFAULT = false;
+ public static final String HIVE_LOCK_ENABLED = "engine.hive.lock-enabled";
+ public static final boolean HIVE_LOCK_ENABLED_DEFAULT = true;
+
public static final String WRITE_DISTRIBUTION_MODE = "write.distribution-mode";
public static final String WRITE_DISTRIBUTION_MODE_NONE = "none";
public static final String WRITE_DISTRIBUTION_MODE_HASH = "hash";
diff --git a/core/src/main/java/org/apache/iceberg/hadoop/ConfigProperties.java b/core/src/main/java/org/apache/iceberg/hadoop/ConfigProperties.java
index a8bc21af06..f87b23b3d5 100644
--- a/core/src/main/java/org/apache/iceberg/hadoop/ConfigProperties.java
+++ b/core/src/main/java/org/apache/iceberg/hadoop/ConfigProperties.java
@@ -23,5 +23,6 @@ public class ConfigProperties {
private ConfigProperties() {}
public static final String ENGINE_HIVE_ENABLED = "iceberg.engine.hive.enabled";
+ public static final String LOCK_HIVE_ENABLED = "iceberg.engine.hive.lock-enabled";
public static final String KEEP_HIVE_STATS = "iceberg.hive.keep.stats";
}
diff --git a/docs/configuration.md b/docs/configuration.md
index 8efd8fc12a..b2c190c134 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -178,8 +178,21 @@ The HMS table locking is a 2-step process:
| iceberg.hive.lock-heartbeat-interval-ms | 240000 (4 min) | The heartbeat interval for the HMS locks. |
| iceberg.hive.metadata-refresh-max-retries | 2 | Maximum number of retries when the metadata file is missing |
| iceberg.hive.table-level-lock-evict-ms | 600000 (10 min) | The timeout for the JVM table lock is |
+| iceberg.engine.hive.lock-enabled | true | Use HMS locks to ensure atomicity of commits |
Note: `iceberg.hive.lock-check-max-wait-ms` and `iceberg.hive.lock-heartbeat-interval-ms` should be less than the [transaction timeout](https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties#ConfigurationProperties-hive.txn.timeout)
of the Hive Metastore (`hive.txn.timeout` or `metastore.txn.timeout` in the newer versions). Otherwise, the heartbeats on the lock (which happens during the lock checks) would end up expiring in the
Hive Metastore before the lock is retried from Iceberg.
+Warn: Setting `iceberg.engine.hive.lock-enabled`=`false` will cause HiveCatalog to commit to tables without using Hive locks.
+This should only be set to `false` if all following conditions are met:
+ - [HIVE-26882](https://issues.apache.org/jira/browse/HIVE-26882)
+is available on the Hive Metastore server
+ - All other HiveCatalogs committing to tables that this HiveCatalog commits to are also on Iceberg 1.3 or later
+ - All other HiveCatalogs committing to tables that this HiveCatalog commits to have also disabled Hive locks on commit.
+
+**Failing to ensure these conditions risks corrupting the table.**
+
+Even with `iceberg.engine.hive.lock-enabled` set to `false`, a HiveCatalog can still use locks for individual tables by setting the table property `engine.hive.lock-enabled`=`true`.
+This is useful in the case where other HiveCatalogs cannot be upgraded and set to commit without using Hive locks.
+
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 5c51af2f61..2723353741 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
@@ -80,6 +80,8 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
// characters, see https://issues.apache.org/jira/browse/HIVE-12274
// set to 0 to not expose Iceberg metadata in HMS Table properties.
private static final String HIVE_TABLE_PROPERTY_MAX_SIZE = "iceberg.hive.table-property-max-size";
+ private static final String NO_LOCK_EXPECTED_KEY = "expected_parameter_key";
+ private static final String NO_LOCK_EXPECTED_VALUE = "expected_parameter_value";
private static final long HIVE_TABLE_PROPERTY_MAX_SIZE_DEFAULT = 32672;
private static final int HIVE_ICEBERG_METADATA_REFRESH_MAX_RETRIES_DEFAULT = 2;
private static final BiMap<String, String> ICEBERG_TO_HMS_TRANSLATION =
@@ -187,7 +189,7 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
CommitStatus commitStatus = CommitStatus.FAILURE;
boolean updateHiveTable = false;
- HiveLock lock = lockObject();
+ HiveLock lock = lockObject(metadata);
try {
lock.lock();
@@ -242,7 +244,8 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
lock.ensureActive();
try {
- persistTable(tbl, updateHiveTable);
+ persistTable(
+ tbl, updateHiveTable, hiveLockEnabled(metadata, conf) ? null : baseMetadataLocation);
lock.ensureActive();
commitStatus = CommitStatus.SUCCESS;
@@ -263,6 +266,15 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
throw e;
} catch (Throwable e) {
+ if (e.getMessage()
+ .contains(
+ "The table has been modified. The parameter value for key '"
+ + HiveTableOperations.METADATA_LOCATION_PROP
+ + "' is")) {
+ throw new CommitFailedException(
+ e, "The table %s.%s has been modified concurrently", database, tableName);
+ }
+
if (e.getMessage() != null
&& e.getMessage().contains("Table/View 'HIVE_LOCKS' does not exist")) {
throw new RuntimeException(
@@ -307,12 +319,23 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
}
@VisibleForTesting
- void persistTable(Table hmsTable, boolean updateHiveTable)
+ void persistTable(Table hmsTable, boolean updateHiveTable, String expectedMetadataLocation)
throws TException, InterruptedException {
if (updateHiveTable) {
metaClients.run(
client -> {
- MetastoreUtil.alterTable(client, database, tableName, hmsTable);
+ MetastoreUtil.alterTable(
+ client,
+ database,
+ tableName,
+ hmsTable,
+ expectedMetadataLocation != null
+ ? ImmutableMap.of(
+ NO_LOCK_EXPECTED_KEY,
+ METADATA_LOCATION_PROP,
+ NO_LOCK_EXPECTED_VALUE,
+ expectedMetadataLocation)
+ : ImmutableMap.of());
return null;
});
} else {
@@ -572,8 +595,39 @@ public class HiveTableOperations extends BaseMetastoreTableOperations {
ConfigProperties.ENGINE_HIVE_ENABLED, TableProperties.ENGINE_HIVE_ENABLED_DEFAULT);
}
+ /**
+ * Returns if the hive locking should be enabled on the table, or not.
+ *
+ * <p>The decision is made like this:
+ *
+ * <ol>
+ * <li>Table property value {@link TableProperties#HIVE_LOCK_ENABLED}
+ * <li>If the table property is not set then check the hive-site.xml property value {@link
+ * ConfigProperties#LOCK_HIVE_ENABLED}
+ * <li>If none of the above is enabled then use the default value {@link
+ * TableProperties#HIVE_LOCK_ENABLED_DEFAULT}
+ * </ol>
+ *
+ * @param metadata Table metadata to use
+ * @param conf The hive configuration to use
+ * @return if the hive engine related values should be enabled or not
+ */
+ private static boolean hiveLockEnabled(TableMetadata metadata, Configuration conf) {
+ if (metadata.properties().get(TableProperties.HIVE_LOCK_ENABLED) != null) {
+ // We know that the property is set, so default value will not be used,
+ return metadata.propertyAsBoolean(TableProperties.HIVE_LOCK_ENABLED, false);
+ }
+
+ return conf.getBoolean(
+ ConfigProperties.LOCK_HIVE_ENABLED, TableProperties.HIVE_LOCK_ENABLED_DEFAULT);
+ }
+
@VisibleForTesting
- HiveLock lockObject() {
- return new MetastoreLock(conf, metaClients, catalogName, database, tableName);
+ HiveLock lockObject(TableMetadata metadata) {
+ if (hiveLockEnabled(metadata, conf)) {
+ return new MetastoreLock(conf, metaClients, catalogName, database, tableName);
+ } else {
+ return new NoLock();
+ }
}
}
diff --git a/hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreUtil.java b/hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreUtil.java
index 7d9dd32e4c..83ff2b60d0 100644
--- a/hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreUtil.java
+++ b/hive-metastore/src/main/java/org/apache/iceberg/hive/MetastoreUtil.java
@@ -18,12 +18,14 @@
*/
package org.apache.iceberg.hive;
+import java.util.Map;
import org.apache.hadoop.hive.common.StatsSetupConst;
import org.apache.hadoop.hive.metastore.IMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.EnvironmentContext;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.iceberg.common.DynMethods;
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap;
+import org.apache.iceberg.relocated.com.google.common.collect.Maps;
public class MetastoreUtil {
private static final DynMethods.UnboundMethod ALTER_TABLE =
@@ -48,14 +50,28 @@ public class MetastoreUtil {
private MetastoreUtil() {}
/**
- * Calls alter_table method using the metastore client. If possible, an environmental context will
- * be used that turns off stats updates to avoid recursive listing.
+ * Calls alter_table method using the metastore client. If the HMS supports it, environmental
+ * context will be set in a way that turns off stats updates to avoid recursive file listing.
*/
public static void alterTable(
IMetaStoreClient client, String databaseName, String tblName, Table table) {
- EnvironmentContext envContext =
- new EnvironmentContext(
- ImmutableMap.of(StatsSetupConst.DO_NOT_UPDATE_STATS, StatsSetupConst.TRUE));
- ALTER_TABLE.invoke(client, databaseName, tblName, table, envContext);
+ alterTable(client, databaseName, tblName, table, ImmutableMap.of());
+ }
+
+ /**
+ * Calls alter_table method using the metastore client. If the HMS supports it, environmental
+ * context will be set in a way that turns off stats updates to avoid recursive file listing.
+ */
+ public static void alterTable(
+ IMetaStoreClient client,
+ String databaseName,
+ String tblName,
+ Table table,
+ Map<String, String> extraEnv) {
+ Map<String, String> env = Maps.newHashMapWithExpectedSize(extraEnv.size() + 1);
+ env.putAll(extraEnv);
+ env.put(StatsSetupConst.DO_NOT_UPDATE_STATS, StatsSetupConst.TRUE);
+
+ ALTER_TABLE.invoke(client, databaseName, tblName, table, new EnvironmentContext(env));
}
}
diff --git a/core/src/main/java/org/apache/iceberg/hadoop/ConfigProperties.java b/hive-metastore/src/main/java/org/apache/iceberg/hive/NoLock.java
similarity index 59%
copy from core/src/main/java/org/apache/iceberg/hadoop/ConfigProperties.java
copy to hive-metastore/src/main/java/org/apache/iceberg/hive/NoLock.java
index a8bc21af06..8085d11c82 100644
--- a/core/src/main/java/org/apache/iceberg/hadoop/ConfigProperties.java
+++ b/hive-metastore/src/main/java/org/apache/iceberg/hive/NoLock.java
@@ -16,12 +16,29 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.iceberg.hadoop;
+package org.apache.iceberg.hive;
-public class ConfigProperties {
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
- private ConfigProperties() {}
+public class NoLock implements HiveLock {
+ public NoLock() {
+ Preconditions.checkArgument(
+ HiveVersion.min(HiveVersion.HIVE_2),
+ "Minimally Hive 2 HMS client is needed to use HIVE-26882 based locking");
+ }
- public static final String ENGINE_HIVE_ENABLED = "iceberg.engine.hive.enabled";
- public static final String KEEP_HIVE_STATS = "iceberg.hive.keep.stats";
+ @Override
+ public void lock() throws LockException {
+ // no-op
+ }
+
+ @Override
+ public void ensureActive() throws LockException {
+ // no-op
+ }
+
+ @Override
+ public void unlock() {
+ // no-op
+ }
}
diff --git a/hive-metastore/src/test/java/org/apache/iceberg/hive/TestHiveCommitLocks.java b/hive-metastore/src/test/java/org/apache/iceberg/hive/TestHiveCommitLocks.java
index d64653301e..c687ae36a6 100644
--- a/hive-metastore/src/test/java/org/apache/iceberg/hive/TestHiveCommitLocks.java
+++ b/hive-metastore/src/test/java/org/apache/iceberg/hive/TestHiveCommitLocks.java
@@ -33,6 +33,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Collections;
+import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -42,6 +43,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.IMetaStoreClient;
+import org.apache.hadoop.hive.metastore.api.EnvironmentContext;
import org.apache.hadoop.hive.metastore.api.LockRequest;
import org.apache.hadoop.hive.metastore.api.LockResponse;
import org.apache.hadoop.hive.metastore.api.LockState;
@@ -52,6 +54,7 @@ import org.apache.iceberg.HasTableOperations;
import org.apache.iceberg.Table;
import org.apache.iceberg.TableMetadata;
import org.apache.iceberg.exceptions.CommitFailedException;
+import org.apache.iceberg.hadoop.ConfigProperties;
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap;
import org.apache.iceberg.relocated.com.google.common.collect.Lists;
import org.apache.iceberg.types.Types;
@@ -494,4 +497,42 @@ public class TestHiveCommitLocks extends HiveTableBaseTest {
"Failed to heartbeat for hive lock. Failed to heart beat.",
() -> spyOps.doCommit(metadataV2, metadataV1));
}
+
+ @Test
+ public void testNoLockCallsWithNoLock() throws TException {
+ Configuration confWithLock = new Configuration(overriddenHiveConf);
+ confWithLock.setBoolean(ConfigProperties.LOCK_HIVE_ENABLED, false);
+
+ HiveTableOperations noLockSpyOps =
+ spy(
+ new HiveTableOperations(
+ confWithLock,
+ spyCachedClientPool,
+ ops.io(),
+ catalog.name(),
+ TABLE_IDENTIFIER.namespace().level(0),
+ TABLE_IDENTIFIER.name()));
+
+ ArgumentCaptor<EnvironmentContext> contextCaptor =
+ ArgumentCaptor.forClass(EnvironmentContext.class);
+
+ doNothing()
+ .when(spyClient)
+ .alter_table_with_environmentContext(any(), any(), any(), contextCaptor.capture());
+
+ noLockSpyOps.doCommit(metadataV2, metadataV1);
+
+ // Make sure that the locking is not used
+ verify(spyClient, never()).lock(any(LockRequest.class));
+ verify(spyClient, never()).checkLock(any(Long.class));
+ verify(spyClient, never()).heartbeat(any(Long.class), any(Long.class));
+ verify(spyClient, never()).unlock(any(Long.class));
+
+ // Make sure that the expected parameter context values are set
+ Map<String, String> context = contextCaptor.getValue().getProperties();
+ Assert.assertEquals(3, context.size());
+ Assert.assertEquals(
+ context.get("expected_parameter_key"), HiveTableOperations.METADATA_LOCATION_PROP);
+ Assert.assertEquals(context.get("expected_parameter_value"), metadataV2.metadataFileLocation());
+ }
}
diff --git a/hive-metastore/src/test/java/org/apache/iceberg/hive/TestHiveCommits.java b/hive-metastore/src/test/java/org/apache/iceberg/hive/TestHiveCommits.java
index b9799cefe6..96c39ce30d 100644
--- a/hive-metastore/src/test/java/org/apache/iceberg/hive/TestHiveCommits.java
+++ b/hive-metastore/src/test/java/org/apache/iceberg/hive/TestHiveCommits.java
@@ -21,12 +21,12 @@ package org.apache.iceberg.hive;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.io.File;
-import java.net.UnknownHostException;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.iceberg.AssertHelpers;
import org.apache.iceberg.HasTableOperations;
@@ -35,6 +35,7 @@ import org.apache.iceberg.Table;
import org.apache.iceberg.TableMetadata;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.iceberg.exceptions.AlreadyExistsException;
+import org.apache.iceberg.exceptions.CommitFailedException;
import org.apache.iceberg.exceptions.CommitStateUnknownException;
import org.apache.iceberg.exceptions.ValidationException;
import org.apache.iceberg.types.Types;
@@ -45,7 +46,7 @@ import org.junit.Test;
public class TestHiveCommits extends HiveTableBaseTest {
@Test
- public void testSuppressUnlockExceptions() throws TException, InterruptedException {
+ public void testSuppressUnlockExceptions() {
Table table = catalog.loadTable(TABLE_IDENTIFIER);
HiveTableOperations ops = (HiveTableOperations) ((HasTableOperations) table).operations();
@@ -63,7 +64,7 @@ public class TestHiveCommits extends HiveTableBaseTest {
AtomicReference<HiveLock> lockRef = new AtomicReference<>();
- when(spyOps.lockObject())
+ when(spyOps.lockObject(metadataV1))
.thenAnswer(
i -> {
HiveLock lock = (HiveLock) i.callRealMethod();
@@ -259,8 +260,7 @@ public class TestHiveCommits extends HiveTableBaseTest {
* because it isn't the current one during the recheck phase.
*/
@Test
- public void testThriftExceptionConcurrentCommit()
- throws TException, InterruptedException, UnknownHostException {
+ public void testThriftExceptionConcurrentCommit() throws TException, InterruptedException {
Table table = catalog.loadTable(TABLE_IDENTIFIER);
HiveTableOperations ops = (HiveTableOperations) ((HasTableOperations) table).operations();
@@ -279,11 +279,11 @@ public class TestHiveCommits extends HiveTableBaseTest {
AtomicReference<HiveLock> lock = new AtomicReference<>();
doAnswer(
l -> {
- lock.set(ops.lockObject());
+ lock.set(ops.lockObject(metadataV1));
return lock.get();
})
.when(spyOps)
- .lockObject();
+ .lockObject(metadataV1);
concurrentCommitAndThrowException(ops, spyOps, table, lock);
@@ -320,6 +320,47 @@ public class TestHiveCommits extends HiveTableBaseTest {
() -> catalog.createTable(TABLE_IDENTIFIER, schema, PartitionSpec.unpartitioned()));
}
+ /** Uses NoLock and pretends we throw an error because of a concurrent commit */
+ @Test
+ public void testNoLockThriftExceptionConcurrentCommit() throws TException, InterruptedException {
+ Table table = catalog.loadTable(TABLE_IDENTIFIER);
+ HiveTableOperations ops = (HiveTableOperations) ((HasTableOperations) table).operations();
+
+ TableMetadata metadataV1 = ops.current();
+
+ table.updateSchema().addColumn("n", Types.IntegerType.get()).commit();
+
+ ops.refresh();
+
+ TableMetadata metadataV2 = ops.current();
+
+ Assert.assertEquals(2, ops.current().schema().columns().size());
+
+ HiveTableOperations spyOps = spy(ops);
+
+ // Sets NoLock
+ doReturn(new NoLock()).when(spyOps).lockObject(any());
+
+ // Simulate a concurrent table modification error
+ doThrow(
+ new RuntimeException(
+ "MetaException(message:The table has been modified. The parameter value for key 'metadata_location' is"))
+ .when(spyOps)
+ .persistTable(any(), anyBoolean(), any());
+
+ // Should throw a CommitFailedException so the commit could be retried
+ AssertHelpers.assertThrows(
+ "Should throw CommitFailedException since the table has been modified concurrently",
+ CommitFailedException.class,
+ "has been modified concurrently",
+ () -> spyOps.commit(metadataV2, metadataV1));
+
+ ops.refresh();
+ Assert.assertEquals("Current metadata should not have changed", metadataV2, ops.current());
+ Assert.assertTrue("Current metadata should still exist", metadataFileExists(metadataV2));
+ Assert.assertEquals("New metadata files should not exist", 2, metadataFileCount(ops.current()));
+ }
+
private void commitAndThrowException(
HiveTableOperations realOperations, HiveTableOperations spyOperations)
throws TException, InterruptedException {
@@ -328,11 +369,12 @@ public class TestHiveCommits extends HiveTableBaseTest {
i -> {
org.apache.hadoop.hive.metastore.api.Table tbl =
i.getArgument(0, org.apache.hadoop.hive.metastore.api.Table.class);
- realOperations.persistTable(tbl, true);
+ String location = i.getArgument(2, String.class);
+ realOperations.persistTable(tbl, true, location);
throw new TException("Datacenter on fire");
})
.when(spyOperations)
- .persistTable(any(), anyBoolean());
+ .persistTable(any(), anyBoolean(), any());
}
private void concurrentCommitAndThrowException(
@@ -346,7 +388,8 @@ public class TestHiveCommits extends HiveTableBaseTest {
i -> {
org.apache.hadoop.hive.metastore.api.Table tbl =
i.getArgument(0, org.apache.hadoop.hive.metastore.api.Table.class);
- realOperations.persistTable(tbl, true);
+ String location = i.getArgument(2, String.class);
+ realOperations.persistTable(tbl, true, location);
// Simulate lock expiration or removal
lock.get().unlock();
table.refresh();
@@ -354,14 +397,14 @@ public class TestHiveCommits extends HiveTableBaseTest {
throw new TException("Datacenter on fire");
})
.when(spyOperations)
- .persistTable(any(), anyBoolean());
+ .persistTable(any(), anyBoolean(), any());
}
private void failCommitAndThrowException(HiveTableOperations spyOperations)
throws TException, InterruptedException {
doThrow(new TException("Datacenter on fire"))
.when(spyOperations)
- .persistTable(any(), anyBoolean());
+ .persistTable(any(), anyBoolean(), any());
}
private void breakFallbackCatalogCommitCheck(HiveTableOperations spyOperations) {