浏览代码

HDFS-15500. In-order deletion of snapshots: Diff lists must be update only in the last snapshot. (#2233)

Tsz-Wo Nicholas Sze 4 年之前
父节点
当前提交
41182a9b6d

+ 6 - 0
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

@@ -1569,6 +1569,12 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
       // null in some unit tests
       haContext.checkOperation(op);
     }
+
+    boolean assertsEnabled = false;
+    assert assertsEnabled = true; // Intentional side effect!!!
+    if (assertsEnabled && op == OperationCategory.WRITE) {
+      getSnapshotManager().initThreadLocals();
+    }
   }
   
   /**

+ 5 - 1
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/AbstractINodeDiffList.java

@@ -76,7 +76,11 @@ abstract class AbstractINodeDiffList<N extends INode,
     if (diffs == null) {
       return;
     }
-    int snapshotIndex = diffs.binarySearch(snapshot);
+    final int snapshotIndex = diffs.binarySearch(snapshot);
+    // DeletionOrdered: only can remove the element at index 0 and no prior
+    //                  check snapshotIndex <= 0 since the diff may not exist
+    assert !SnapshotManager.isDeletionOrdered()
+        || (snapshotIndex <= 0 && prior == Snapshot.NO_SNAPSHOT_ID);
 
     D removed;
     if (snapshotIndex == 0) {

+ 2 - 0
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/DiffListByArrayList.java

@@ -57,6 +57,8 @@ public class DiffListByArrayList<T extends Comparable<Integer>>
 
   @Override
   public T remove(int i) {
+    // DeletionOrdered: only can remove the element at index 0
+    assert !SnapshotManager.isDeletionOrdered() || i == 0;
     return list.remove(i);
   }
 

+ 2 - 0
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/DirectoryWithSnapshotFeature.java

@@ -175,6 +175,8 @@ public class DirectoryWithSnapshotFeature implements INode.Feature {
         final INode.ReclaimContext reclaimContext,
         final INodeDirectory currentDir,
         final DirectoryDiff posterior) {
+      // DeletionOrdered: must not combine posterior
+      assert !SnapshotManager.isDeletionOrdered();
       diff.combinePosterior(posterior.diff, new Diff.Processor<INode>() {
         /** Collect blocks for deleted files. */
         @Override

+ 12 - 0
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/snapshot/SnapshotManager.java

@@ -95,6 +95,18 @@ public class SnapshotManager implements SnapshotStatsMXBean {
   static final long DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED_GC_PERIOD_MS_DEFAULT
       = 5 * 60_000L; //5 minutes
 
+  private static final ThreadLocal<Boolean> DELETION_ORDERED
+      = new ThreadLocal<>();
+
+  static boolean isDeletionOrdered() {
+    final Boolean b = DELETION_ORDERED.get();
+    return b != null? b: false;
+  }
+
+  public void initThreadLocals() {
+    DELETION_ORDERED.set(isSnapshotDeletionOrdered());
+  }
+
   private final FSDirectory fsdir;
   private boolean captureOpenFiles;
   /**