difin commented on code in PR #6930:
URL: https://github.com/apache/hive/pull/6930#discussion_r4428784556


##########
iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergMetaHook.java:
##########
@@ -307,24 +305,38 @@ public void 
preAlterTable(org.apache.hadoop.hive.metastore.api.Table hmsTable, E
     }
   }
 
-  private HiveLock lockObject(org.apache.hadoop.hive.metastore.api.Table 
hmsTable) {
-    if (!HiveTableOperations.hiveLockEnabled(hmsTable.getParameters(), conf) ||
-        SessionStateUtil.getQueryState(conf)
-            .map(QueryState::getHiveOperation)
-            .filter(opType -> HiveOperation.QUERY == opType)
-            .isPresent()) {
+  /**
+   * The HMS lock Hive's Iceberg commits take, for an alter that commits to 
Iceberg and writes the metadata_location to
+   * HMS. An alter without an operation type commits nothing to Iceberg: the 
metadata_location CAS protects it instead.
+   */
+  private HiveLock lockObject(org.apache.hadoop.hive.metastore.api.Table 
hmsTable, EnvironmentContext context) {
+    Map<String, String> params = hmsTable.getParameters();
+    boolean writesMetadataLocation = currentAlterTableOp != null &&
+        
!Boolean.parseBoolean(context.getProperties().get(SKIP_METASTORE_ALTER)) &&
+        
params.containsKey(BaseMetastoreTableOperations.METADATA_LOCATION_PROP);
+    if (!writesMetadataLocation || 
!HiveTableOperations.hiveLockEnabled(params, conf)) {
       return new NoLock();
-    } else {
-      return new MetastoreLock(
-          conf,
-          new CachedClientPool(conf, Maps.fromProperties(tableProperties)),
-          tableProperties.getProperty(Catalogs.NAME), hmsTable.getDbName(),
-          hmsTable.getTableName());
     }
+    return new MetastoreLock(
+        conf,
+        new CachedClientPool(conf, Maps.fromProperties(tableProperties)),
+        Catalogs.catalogName(conf, tableProperties),
+        hmsTable.getDbName(),
+        hmsTable.getTableName());
   }
 
   private void doPreAlterTable(org.apache.hadoop.hive.metastore.api.Table 
hmsTable, EnvironmentContext context)
-      throws MetaException {
+      throws TException, InterruptedException {
+    if (currentAlterTableOp == null) {
+      // nothing to commit to Iceberg: read the current metadata_location from 
HMS, as HiveTableOperations does
+      if 
(hmsTable.getParameters().containsKey(BaseMetastoreTableOperations.METADATA_LOCATION_PROP))
 {
+        String currentMetadataLocation = new CachedClientPool(conf, 
Maps.fromProperties(tableProperties))
+            .run(client -> client.getTable(hmsTable.getDbName(), 
hmsTable.getTableName()))
+            
.getParameters().get(BaseMetastoreTableOperations.METADATA_LOCATION_PROP);
+        keepCurrentMetadataLocation(hmsTable.getParameters(), 
currentMetadataLocation, context);
+      }
+      return;
+    }

Review Comment:
   For alters with no operation type (basic stats, column stats state, TOUCH), 
the CAS now makes a concurrent Iceberg commit cause a rejection. That rejection 
reaches the statement when `hive.stats.reliable=true` 
(`BasicStatsTask.aggregateStats` and the rethrow in `ColStatsProcessor`).
   
   For a single-table autocommit INSERT, UPDATE, DELETE or MERGE, the snapshot 
is already published in the move task (`HiveIcebergOutputCommitter.commit` → 
`txn.commitTransaction()`), before the stats task runs. The driver's rollback 
doesn't revert it. The user then sees a failed statement whose rows are already 
in the table, and a retry duplicates them. Explicit transactions and 
multi-table inserts aren't affected, because `HiveTxnCoordinator` stages the 
commit until the Hive transaction commits.
   
   These alters commit nothing to Iceberg, so a rejection here can't be a real 
conflict. Could we retry them a few times, re-reading metadata_location each 
time, instead of failing? Either in the hook or around `db.alterTable` in the 
stats tasks. A test with a concurrent commit and `hive.stats.reliable=true` 
would cover this.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to