Skip to content

Commit 41182a9

Browse files
authored
HDFS-15500. In-order deletion of snapshots: Diff lists must be update only in the last snapshot. (#2233)
1 parent d8aaa8c commit 41182a9

5 files changed

Lines changed: 27 additions & 1 deletion

File tree

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,12 @@ public void checkOperation(OperationCategory op) throws StandbyException {
15691569
// null in some unit tests
15701570
haContext.checkOperation(op);
15711571
}
1572+
1573+
boolean assertsEnabled = false;
1574+
assert assertsEnabled = true; // Intentional side effect!!!
1575+
if (assertsEnabled && op == OperationCategory.WRITE) {
1576+
getSnapshotManager().initThreadLocals();
1577+
}
15721578
}
15731579

15741580
/**

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ public final void deleteSnapshotDiff(INode.ReclaimContext reclaimContext,
7676
if (diffs == null) {
7777
return;
7878
}
79-
int snapshotIndex = diffs.binarySearch(snapshot);
79+
final int snapshotIndex = diffs.binarySearch(snapshot);
80+
// DeletionOrdered: only can remove the element at index 0 and no prior
81+
// check snapshotIndex <= 0 since the diff may not exist
82+
assert !SnapshotManager.isDeletionOrdered()
83+
|| (snapshotIndex <= 0 && prior == Snapshot.NO_SNAPSHOT_ID);
8084

8185
D removed;
8286
if (snapshotIndex == 0) {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public int size() {
5757

5858
@Override
5959
public T remove(int i) {
60+
// DeletionOrdered: only can remove the element at index 0
61+
assert !SnapshotManager.isDeletionOrdered() || i == 0;
6062
return list.remove(i);
6163
}
6264

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ void combinePosteriorAndCollectBlocks(
175175
final INode.ReclaimContext reclaimContext,
176176
final INodeDirectory currentDir,
177177
final DirectoryDiff posterior) {
178+
// DeletionOrdered: must not combine posterior
179+
assert !SnapshotManager.isDeletionOrdered();
178180
diff.combinePosterior(posterior.diff, new Diff.Processor<INode>() {
179181
/** Collect blocks for deleted files. */
180182
@Override

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ public class SnapshotManager implements SnapshotStatsMXBean {
9595
static final long DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED_GC_PERIOD_MS_DEFAULT
9696
= 5 * 60_000L; //5 minutes
9797

98+
private static final ThreadLocal<Boolean> DELETION_ORDERED
99+
= new ThreadLocal<>();
100+
101+
static boolean isDeletionOrdered() {
102+
final Boolean b = DELETION_ORDERED.get();
103+
return b != null? b: false;
104+
}
105+
106+
public void initThreadLocals() {
107+
DELETION_ORDERED.set(isSnapshotDeletionOrdered());
108+
}
109+
98110
private final FSDirectory fsdir;
99111
private boolean captureOpenFiles;
100112
/**

0 commit comments

Comments
 (0)