Sfoglia il codice sorgente

HADOOP-8110. Fix trash checkpoint collisions (Jason Lowe via daryn)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1356897 13f79535-47bb-0310-9956-ffa450edef68
Daryn Sharp 13 anni fa
parent
commit
3c2101ae4a

+ 2 - 0
hadoop-common-project/hadoop-common/CHANGES.txt

@@ -167,6 +167,8 @@ Trunk (unreleased changes)
     HADOOP-8548. test-patch.sh shows an incorrect link in Jekins builds
     (Kihwal Lee via bobby)
 
+    HADOOP-8110. Fix trash checkpoint collisions (Jason Lowe via daryn)
+
   OPTIMIZATIONS
 
     HADOOP-7761. Improve the performance of raw comparisons. (todd)

+ 18 - 6
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/TrashPolicyDefault.java

@@ -35,6 +35,7 @@ import org.apache.hadoop.classification.InterfaceAudience;
 import org.apache.hadoop.classification.InterfaceStability;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.conf.Configured;
+import org.apache.hadoop.fs.Options.Rename;
 import org.apache.hadoop.fs.permission.FsAction;
 import org.apache.hadoop.fs.permission.FsPermission;
 
@@ -148,21 +149,32 @@ public class TrashPolicyDefault extends TrashPolicy {
       new IOException("Failed to move to trash: "+path).initCause(cause);
   }
 
+  @SuppressWarnings("deprecation")
   @Override
   public void createCheckpoint() throws IOException {
     if (!fs.exists(current))                     // no trash, no checkpoint
       return;
 
-    Path checkpoint;
+    Path checkpointBase;
     synchronized (CHECKPOINT) {
-      checkpoint = new Path(trash, CHECKPOINT.format(new Date()));
+      checkpointBase = new Path(trash, CHECKPOINT.format(new Date()));
     }
+    Path checkpoint = checkpointBase;
 
-    if (fs.rename(current, checkpoint)) {
-      LOG.info("Created trash checkpoint: "+checkpoint.toUri().getPath());
-    } else {
-      throw new IOException("Failed to checkpoint trash: "+checkpoint);
+    int attempt = 0;
+    while (true) {
+      try {
+        fs.rename(current, checkpoint, Rename.NONE);
+        break;
+      } catch (FileAlreadyExistsException e) {
+        if (++attempt > 1000) {
+          throw new IOException("Failed to checkpoint trash: "+checkpoint);
+        }
+        checkpoint = checkpointBase.suffix("-" + attempt);
+      }
     }
+
+    LOG.info("Created trash checkpoint: "+checkpoint.toUri().getPath());
   }
 
   @Override