diff --git common/src/java/org/apache/hadoop/hive/conf/HiveConf.java common/src/java/org/apache/hadoop/hive/conf/HiveConf.java index e511260..01089d6 100644 --- common/src/java/org/apache/hadoop/hive/conf/HiveConf.java +++ common/src/java/org/apache/hadoop/hive/conf/HiveConf.java @@ -307,6 +307,10 @@ DROPIGNORESNONEXISTENT("hive.exec.drop.ignorenonexistent", true, "Do not report an error if DROP TABLE/VIEW specifies a non-existent table/view"), + DROPIGNORESFAILEDFILEREMOVAL("hive.exec.drop.ignorefailedfileremoval", true, + "Do not report an error if DROP TABLE/VIEW fails to delete underlying hdfs files"), + DROPSUCCEEDSONFAILEDFILEREMOVAL("hive.exec.drop.succeedsonfailedfileremoval", true, + "Drop commands that cannot remove hdfs files will succeed"), HIVEIGNOREMAPJOINHINT("hive.ignore.mapjoin.hint", true, "Ignore the mapjoin hint"), diff --git metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java index 86e1cb9..a8409d2 100644 --- metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java @@ -955,24 +955,37 @@ private void drop_database_core(RawStore ms, if (ms.dropDatabase(name)) { success = ms.commitTransaction(); } + if (success && deleteData) { + boolean ignoreFailure = hiveConf.getBoolVar(ConfVars.DROPIGNORESFAILEDFILEREMOVAL); + try { + // Delete the data in the partitions which have other locations + deletePartitionData(partitionPaths, ignoreFailure); + // Delete the data in the tables which have other locations + for (Path tablePath : tablePaths) { + deleteTableData(tablePath, ignoreFailure); + } + // Delete the data in the database + try { + wh.deleteDir(new Path(db.getLocationUri()), true); + } catch (MetaException e) { + LOG.error("Failed to delete database directory: " + db.getLocationUri() + + " " + e.getMessage()); + if (!ignoreFailure) { + throw e; + } + } + } + catch (MetaException e) { + if (hiveConf.getBoolVar(ConfVars.DROPSUCCEEDSONFAILEDFILEREMOVAL)) { + success = false; + } + throw e; + } + } + } finally { if (!success) { ms.rollbackTransaction(); - } else if (deleteData) { - // Delete the data in the partitions which have other locations - deletePartitionData(partitionPaths); - // Delete the data in the tables which have other locations - for (Path tablePath : tablePaths) { - deleteTableData(tablePath); - } - // Delete the data in the database - try { - wh.deleteDir(new Path(db.getLocationUri()), true); - } catch (Exception e) { - LOG.error("Failed to delete database directory: " + db.getLocationUri() + - " " + e.getMessage()); - } - // it is not a terrible thing even if the data is not deleted } for (MetaStoreEventListener listener : listeners) { listener.onDropDatabase(new DropDatabaseEvent(db, success, this)); @@ -1411,15 +1424,23 @@ private void drop_table_core(final RawStore ms, final String dbname, final Strin throw new MetaException("Unable to drop table"); } success = ms.commitTransaction(); + if (success && deleteData && !isExternal) { + boolean ignoreFailure = hiveConf.getBoolVar(ConfVars.DROPIGNORESFAILEDFILEREMOVAL); + try { + // Delete the data in the partitions which have other locations + deletePartitionData(partPaths, ignoreFailure); + // Delete the data in the table + deleteTableData(tblPath, ignoreFailure); + } catch (MetaException e) { + if (hiveConf.getBoolVar(ConfVars.DROPSUCCEEDSONFAILEDFILEREMOVAL)) { + success = false; + } + throw e; + } + } } finally { if (!success) { ms.rollbackTransaction(); - } else if (deleteData && !isExternal) { - // Delete the data in the partitions which have other locations - deletePartitionData(partPaths); - // Delete the data in the table - deleteTableData(tblPath); - // ok even if the data is not deleted } for (MetaStoreEventListener listener : listeners) { DropTableEvent dropTableEvent = new DropTableEvent(tbl, success, deleteData, this); @@ -1434,13 +1455,16 @@ private void drop_table_core(final RawStore ms, final String dbname, final Strin * * @param tablePath */ - private void deleteTableData(Path tablePath) { + private void deleteTableData(Path tablePath, boolean ignoreFailure) throws MetaException { if (tablePath != null) { try { wh.deleteDir(tablePath, true); - } catch (Exception e) { + } catch (MetaException e) { LOG.error("Failed to delete table directory: " + tablePath + " " + e.getMessage()); + if (!ignoreFailure) { + throw e; + } } } } @@ -1451,14 +1475,18 @@ private void deleteTableData(Path tablePath) { * * @param partPaths */ - private void deletePartitionData(List partPaths) { + private void deletePartitionData(List partPaths, boolean ignoreFailure) + throws MetaException { if (partPaths != null && !partPaths.isEmpty()) { for (Path partPath : partPaths) { try { wh.deleteDir(partPath, true); - } catch (Exception e) { + } catch (MetaException e) { LOG.error("Failed to delete partition directory: " + partPath + " " + e.getMessage()); + if (!ignoreFailure) { + throw e; + } } } } @@ -3442,14 +3470,21 @@ private boolean drop_index_by_name_core(final RawStore ms, } } success = ms.commitTransaction(); + if (success&& deleteData && tblPath != null) { + try { + boolean ignoreFailure = hiveConf.getBoolVar(ConfVars.DROPIGNORESFAILEDFILEREMOVAL); + deletePartitionData(partPaths, ignoreFailure); + deleteTableData(tblPath, ignoreFailure); + } catch (MetaException e) { + if (hiveConf.getBoolVar(ConfVars.DROPSUCCEEDSONFAILEDFILEREMOVAL)) { + success = false; + } + } + } } finally { if (!success) { ms.rollbackTransaction(); return false; - } else if (deleteData && tblPath != null) { - deletePartitionData(partPaths); - deleteTableData(tblPath); - // ok even if the data is not deleted } } return true;