Skip to content

Commit 2df2dfb

Browse files
authored
HDFS-15817. Rename snapshots while marking them deleted. (apache#2677)
1 parent 0b05dd8 commit 2df2dfb

File tree

4 files changed

+54
-19
lines changed

4 files changed

+54
-19
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ public static String generateDefaultSnapshotName() {
6161
return new SimpleDateFormat(DEFAULT_SNAPSHOT_NAME_PATTERN).format(new Date());
6262
}
6363

64+
public static String generateDeletedSnapshotName(Snapshot s) {
65+
return getSnapshotName(s) + "#" + s.getId();
66+
}
67+
6468
public static String getSnapshotPath(String snapshottableDir,
6569
String snapshotRelativePath) {
6670
final StringBuilder b = new StringBuilder(snapshottableDir);

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import org.apache.hadoop.metrics2.util.MBeans;
6767

6868
import org.apache.hadoop.thirdparty.com.google.common.base.Preconditions;
69+
import org.apache.hadoop.util.Time;
6970
import org.slf4j.Logger;
7071
import org.slf4j.LoggerFactory;
7172

@@ -533,6 +534,8 @@ public void deleteSnapshot(final INodesInPath iip, final String snapshotName,
533534
INodesInPath.append(iip, snapshot.getRoot(),
534535
DFSUtil.string2Bytes(snapshotName)), xattrs,
535536
EnumSet.of(XAttrSetFlag.CREATE, XAttrSetFlag.REPLACE));
537+
renameSnapshot(iip, srcRoot.getFullPathName(), snapshotName,
538+
Snapshot.generateDeletedSnapshotName(snapshot), Time.now());
536539
return;
537540
}
538541

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestOrderedSnapshotDeletion.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,25 @@ public void testOrderedSnapshotDeletion() throws Exception {
9292
assertXAttrSet("s2", hdfs, null);
9393
hdfs.deleteSnapshot(snapshottableDir, "s0");
9494
assertXAttrSet("s2", hdfs, null);
95-
hdfs.deleteSnapshot(snapshottableDir, "s1");
96-
hdfs.deleteSnapshot(snapshottableDir, "s2");
95+
hdfs.deleteSnapshot(snapshottableDir,
96+
getDeletedSnapshotName(hdfs, snapshottableDir, "s1"));
97+
hdfs.deleteSnapshot(snapshottableDir,
98+
getDeletedSnapshotName(hdfs, snapshottableDir, "s2"));
9799
}
98100

99-
static void assertMarkedAsDeleted(Path snapshotRoot, MiniDFSCluster cluster)
100-
throws IOException {
101+
static void assertMarkedAsDeleted(Path snapshotRoot, Path snapshottableDir,
102+
MiniDFSCluster cluster) throws IOException {
103+
final String snapName =
104+
getDeletedSnapshotName(cluster.getFileSystem(), snapshottableDir,
105+
snapshotRoot.getName());
106+
final Path snapPathNew =
107+
SnapshotTestHelper.getSnapshotRoot(snapshottableDir, snapName);
101108
// Check if the path exists
102-
Assert.assertNotNull(cluster.getFileSystem().getFileStatus(snapshotRoot));
109+
Assert.assertNotNull(cluster.getFileSystem().getFileStatus(snapPathNew));
103110

104111
// Check xAttr for snapshotRoot
105112
final INode inode = cluster.getNamesystem().getFSDirectory()
106-
.getINode(snapshotRoot.toString());
113+
.getINode(snapPathNew.toString());
107114
final XAttrFeature f = inode.getXAttrFeature();
108115
final XAttr xAttr = f.getXAttr(XATTR_SNAPSHOT_DELETED);
109116
Assert.assertNotNull(xAttr);
@@ -114,7 +121,7 @@ static void assertMarkedAsDeleted(Path snapshotRoot, MiniDFSCluster cluster)
114121

115122
// Check inode
116123
Assert.assertTrue(inode instanceof Snapshot.Root);
117-
Assert.assertTrue(((Snapshot.Root)inode).isMarkedAsDeleted());
124+
Assert.assertTrue(((Snapshot.Root) inode).isMarkedAsDeleted());
118125
}
119126

120127
static void assertNotMarkedAsDeleted(Path snapshotRoot,
@@ -139,12 +146,16 @@ static void assertNotMarkedAsDeleted(Path snapshotRoot,
139146
void assertXAttrSet(String snapshot,
140147
DistributedFileSystem hdfs, XAttr newXattr)
141148
throws IOException {
142-
hdfs.deleteSnapshot(snapshottableDir, snapshot);
149+
String snapName = getDeletedSnapshotName(hdfs, snapshottableDir, snapshot);
150+
hdfs.deleteSnapshot(snapshottableDir, snapName);
143151
// Check xAttr for parent directory
144-
Path snapshotRoot = SnapshotTestHelper.getSnapshotRoot(snapshottableDir,
145-
snapshot);
146-
assertMarkedAsDeleted(snapshotRoot, cluster);
147-
152+
Path snapshotRoot =
153+
SnapshotTestHelper.getSnapshotRoot(snapshottableDir, snapshot);
154+
assertMarkedAsDeleted(snapshotRoot, snapshottableDir, cluster);
155+
// Check xAttr for parent directory
156+
snapName = getDeletedSnapshotName(hdfs, snapshottableDir, snapshot);
157+
snapshotRoot =
158+
SnapshotTestHelper.getSnapshotRoot(snapshottableDir, snapName);
148159
// Make sure its not user visible
149160
if (cluster.getNameNode().getConf().getBoolean(DFSConfigKeys.
150161
DFS_NAMENODE_XATTRS_ENABLED_KEY,
@@ -261,4 +272,11 @@ public void testSnapshotXAttrWithPreExistingXattrs() throws Exception {
261272
hdfs.createSnapshot(snapshottableDir, "s1");
262273
assertXAttrSet("s1", hdfs, newXAttr);
263274
}
275+
276+
public static String getDeletedSnapshotName(DistributedFileSystem hdfs,
277+
Path snapshottableDir, String snapshot) throws IOException {
278+
return Arrays.stream(hdfs.getSnapshotListing(snapshottableDir))
279+
.filter(p -> p.getFullPath().getName().startsWith(snapshot)).findFirst()
280+
.get().getFullPath().getName();
281+
}
264282
}

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestOrderedSnapshotDeletionGc.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import static org.apache.hadoop.hdfs.server.namenode.snapshot.SnapshotManager.DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED_GC_PERIOD_MS;
5151
import static org.apache.hadoop.hdfs.server.namenode.snapshot.TestOrderedSnapshotDeletion.assertMarkedAsDeleted;
5252
import static org.apache.hadoop.hdfs.server.namenode.snapshot.TestOrderedSnapshotDeletion.assertNotMarkedAsDeleted;
53+
import static org.apache.hadoop.hdfs.server.namenode.snapshot.TestOrderedSnapshotDeletion.getDeletedSnapshotName;
5354
import static org.junit.Assert.assertEquals;
5455
import static org.junit.Assert.assertTrue;
5556

@@ -112,23 +113,32 @@ public void testSingleDir() throws Exception {
112113
hdfs.deleteSnapshot(snapshottableDir, "s2");
113114
assertNotMarkedAsDeleted(s0path, cluster);
114115
assertNotMarkedAsDeleted(s1path, cluster);
115-
assertMarkedAsDeleted(s2path, cluster);
116+
assertMarkedAsDeleted(s2path, snapshottableDir, cluster);
117+
final Path s2pathNew = new Path(s2path.getParent(),
118+
getDeletedSnapshotName(hdfs, snapshottableDir, s2path.getName()));
119+
Assert.assertFalse(exist(s2path, hdfs));
120+
Assert.assertTrue(exist(s2pathNew, hdfs));
121+
Assert.assertFalse(s2path.equals(s2pathNew));
116122

117123
hdfs.deleteSnapshot(snapshottableDir, "s1");
118124
assertNotMarkedAsDeleted(s0path, cluster);
119-
assertMarkedAsDeleted(s1path, cluster);
120-
assertMarkedAsDeleted(s2path, cluster);
121-
125+
assertMarkedAsDeleted(s1path, snapshottableDir, cluster);
126+
assertMarkedAsDeleted(s2path, snapshottableDir, cluster);
127+
final Path s1pathNew = new Path(s1path.getParent(),
128+
getDeletedSnapshotName(hdfs, snapshottableDir, s1path.getName()));
129+
Assert.assertFalse(exist(s1path, hdfs));
130+
Assert.assertTrue(exist(s1pathNew, hdfs));
131+
Assert.assertFalse(s1path.equals(s1pathNew));
122132
// should not be gc'ed
123133
Thread.sleep(10*GC_PERIOD);
124134
assertNotMarkedAsDeleted(s0path, cluster);
125-
assertMarkedAsDeleted(s1path, cluster);
126-
assertMarkedAsDeleted(s2path, cluster);
135+
assertMarkedAsDeleted(s1path, snapshottableDir, cluster);
136+
assertMarkedAsDeleted(s2path, snapshottableDir, cluster);
127137

128138
hdfs.deleteSnapshot(snapshottableDir, "s0");
129139
Assert.assertFalse(exist(s0path, hdfs));
130140

131-
waitForGc(Arrays.asList(s1path, s2path), hdfs);
141+
waitForGc(Arrays.asList(s1pathNew, s2pathNew), hdfs);
132142
// total no of edit log records created for delete snapshot will be equal
133143
// to sum of no of user deleted snapshots and no of snapshots gc'ed with
134144
// snapshotDeletion gc thread

0 commit comments

Comments
 (0)