diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java index bae39ac..c8ed1d2 100644 --- a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java +++ b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveAlterHandler.java @@ -111,10 +111,9 @@ public void alterTable(RawStore msdb, Warehouse wh, String dbname, FileSystem destFs = null; boolean success = false; - boolean moveData = false; + boolean dataWasMoved = false; boolean rename = false; Table oldt = null; - List> altps = new ArrayList>(); List transactionalListeners = null; if (handler != null) { transactionalListeners = handler.getTransactionalListeners(); @@ -212,7 +211,6 @@ public void alterTable(RawStore msdb, Warehouse wh, String dbname, destFs = wh.getFs(destPath); newt.getSd().setLocation(destPath.toString()); - moveData = true; // check that destination does not exist otherwise we will be // overwriting data @@ -222,18 +220,21 @@ public void alterTable(RawStore msdb, Warehouse wh, String dbname, + " is on a different file system than the old location " + srcPath + ". This operation is not supported"); } + try { - srcFs.exists(srcPath); // check that src exists and also checks - // permissions necessary if (destFs.exists(destPath)) { throw new InvalidOperationException("New location for this table " + newt.getDbName() + "." + newt.getTableName() + " already exists : " + destPath); } + // check that src exists and also checks permissions necessary, rename src to dest + if (srcFs.exists(srcPath) && srcFs.rename(srcPath, destPath)) { + dataWasMoved = true; + } } catch (IOException e) { - throw new InvalidOperationException("Unable to access new location " - + destPath + " for table " + newt.getDbName() + "." - + newt.getTableName()); + throw new InvalidOperationException("Alter Table operation for " + dbname + "." + name + + " failed to move data to " + destPath + " due to: '" + getSimpleMessage(e) + + "' See hive log file for details."); } String oldTblLocPath = srcPath.toUri().getPath(); String newTblLocPath = destPath.toUri().getPath(); @@ -246,7 +247,6 @@ public void alterTable(RawStore msdb, Warehouse wh, String dbname, URI oldUri = new Path(oldPartLoc).toUri(); String newPath = oldUri.getPath().replace(oldTblLocPath, newTblLocPath); Path newPartLocPath = new Path(oldUri.getScheme(), oldUri.getAuthority(), newPath); - altps.add(ObjectPair.create(part, part.getSd().getLocation())); part.getSd().setLocation(newPartLocPath.toString()); String oldPartName = Warehouse.makePartName(oldt.getPartitionKeys(), part.getValues()); try { @@ -290,51 +290,22 @@ public void alterTable(RawStore msdb, Warehouse wh, String dbname, } finally { if (!success) { msdb.rollbackTransaction(); - } - - if (success && moveData) { - // change the file name in hdfs - // check that src exists otherwise there is no need to copy the data - // rename the src to destination - try { - if (srcFs.exists(srcPath) && !srcFs.rename(srcPath, destPath)) { - throw new IOException("Renaming " + srcPath + " to " + destPath + " failed"); - } - } catch (IOException e) { - LOG.error("Alter Table operation for " + dbname + "." + name + " failed.", e); - boolean revertMetaDataTransaction = false; + if (dataWasMoved) { try { - msdb.openTransaction(); - msdb.alterTable(newt.getDbName(), newt.getTableName(), oldt); - for (ObjectPair pair : altps) { - Partition part = pair.getFirst(); - part.getSd().setLocation(pair.getSecond()); - msdb.alterPartition(newt.getDbName(), name, part.getValues(), part); - } - revertMetaDataTransaction = msdb.commitTransaction(); - } catch (Exception e1) { - // we should log this for manual rollback by administrator - LOG.error("Reverting metadata by HDFS operation failure failed During HDFS operation failed", e1); - LOG.error("Table " + Warehouse.getQualifiedName(newt) + - " should be renamed to " + Warehouse.getQualifiedName(oldt)); - LOG.error("Table " + Warehouse.getQualifiedName(newt) + - " should have path " + srcPath); - for (ObjectPair pair : altps) { - LOG.error("Partition " + Warehouse.getQualifiedName(pair.getFirst()) + - " should have path " + pair.getSecond()); - } - if (!revertMetaDataTransaction) { - msdb.rollbackTransaction(); + if (destFs.exists(destPath)) { + if (!destFs.rename(destPath, srcPath)) { + LOG.error("Failed to restore data from " + destPath + " to " + srcPath + + " in alter table failure. Manual restore is needed."); + } } + } catch (IOException e) { + LOG.error("Failed to restore data from " + destPath + " to " + srcPath + + " in alter table failure. Manual restore is needed."); } - throw new InvalidOperationException("Alter Table operation for " + dbname + "." + name + - " failed to move data due to: '" + getSimpleMessage(e) + "' See hive log file for details."); } + throw new MetaException("Failed to alter table " + dbname + "." + name); } } - if (!success) { - throw new MetaException("Committing the alter table transaction was not successful."); - } } /**