HDFS-15498. Show snapshots deletion status in snapList cmd. (#2181)

This commit is contained in:
bshashikant 2020-08-02 21:59:56 +05:30 committed by GitHub
parent 528a799a78
commit d8a2df25ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 11 deletions

View File

@ -40,6 +40,11 @@ public class SnapshotStatus {
*/ */
private final int snapshotID; private final int snapshotID;
/**
* Whether the snapshot is deleted or not.
*/
private final boolean isDeleted;
/** /**
* Full path of the parent. * Full path of the parent.
*/ */
@ -50,7 +55,7 @@ public SnapshotStatus(long modificationTime, long accessTime,
EnumSet<HdfsFileStatus.Flags> flags, EnumSet<HdfsFileStatus.Flags> flags,
String owner, String group, byte[] localName, String owner, String group, byte[] localName,
long inodeId, int childrenNum, int snapshotID, long inodeId, int childrenNum, int snapshotID,
byte[] parentFullPath) { boolean isDeleted, byte[] parentFullPath) {
this.dirStatus = new HdfsFileStatus.Builder() this.dirStatus = new HdfsFileStatus.Builder()
.isdir(true) .isdir(true)
.mtime(modificationTime) .mtime(modificationTime)
@ -64,13 +69,7 @@ public SnapshotStatus(long modificationTime, long accessTime,
.children(childrenNum) .children(childrenNum)
.build(); .build();
this.snapshotID = snapshotID; this.snapshotID = snapshotID;
this.parentFullPath = parentFullPath; this.isDeleted = isDeleted;
}
public SnapshotStatus(HdfsFileStatus dirStatus,
int snapshotNumber, byte[] parentFullPath) {
this.dirStatus = dirStatus;
this.snapshotID = snapshotNumber;
this.parentFullPath = parentFullPath; this.parentFullPath = parentFullPath;
} }
@ -89,6 +88,13 @@ public int getSnapshotID() {
return snapshotID; return snapshotID;
} }
/**
* @return whether snapshot is deleted
*/
public boolean isDeleted() {
return isDeleted;
}
/** /**
* @return The basic information of the directory * @return The basic information of the directory
*/ */
@ -143,6 +149,7 @@ public static void print(SnapshotStatus[] stats,
+ "%" + maxLen + "s " + "%" + maxLen + "s "
+ "%s " // mod time + "%s " // mod time
+ "%" + maxSnapshotID + "s " + "%" + maxSnapshotID + "s "
+ "%s " // deletion status
+ "%s"; // path + "%s"; // path
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
@ -155,6 +162,7 @@ public static void print(SnapshotStatus[] stats,
String.valueOf(status.dirStatus.getLen()), String.valueOf(status.dirStatus.getLen()),
dateFormat.format(new Date(status.dirStatus.getModificationTime())), dateFormat.format(new Date(status.dirStatus.getModificationTime())),
status.snapshotID, status.snapshotID,
status.isDeleted ? "DELETED" : "ACTIVE",
getSnapshotPath(DFSUtilClient.bytes2String(status.parentFullPath), getSnapshotPath(DFSUtilClient.bytes2String(status.parentFullPath),
status.dirStatus.getLocalName()) status.dirStatus.getLocalName())
); );
@ -166,6 +174,9 @@ private static int maxLength(int n, Object value) {
return Math.max(n, String.valueOf(value).length()); return Math.max(n, String.valueOf(value).length());
} }
/**
* To be used to for collection of snapshot jmx.
*/
public static class Bean { public static class Bean {
private final String path; private final String path;
private final int snapshotID; private final int snapshotID;
@ -173,15 +184,19 @@ public static class Bean {
private final short permission; private final short permission;
private final String owner; private final String owner;
private final String group; private final String group;
private final boolean isDeleted;
public Bean(String path, int snapshotID, long public Bean(String path, int snapshotID, long
modificationTime, short permission, String owner, String group) { modificationTime, short permission, String owner, String group,
boolean isDeleted) {
this.path = path; this.path = path;
this.snapshotID = snapshotID; this.snapshotID = snapshotID;
this.modificationTime = modificationTime; this.modificationTime = modificationTime;
this.permission = permission; this.permission = permission;
this.owner = owner; this.owner = owner;
this.group = group; this.group = group;
this.isDeleted = isDeleted;
} }
public String getPath() { public String getPath() {
@ -207,6 +222,10 @@ public String getOwner() {
public String getGroup() { public String getGroup() {
return group; return group;
} }
public boolean isDeleted() {
return isDeleted;
}
} }
static String getSnapshotPath(String snapshottableDir, static String getSnapshotPath(String snapshottableDir,

View File

@ -1711,6 +1711,7 @@ public static SnapshotStatus convert(
status.getFileId(), status.getFileId(),
status.getChildrenNum(), status.getChildrenNum(),
sdirStatusProto.getSnapshotID(), sdirStatusProto.getSnapshotID(),
sdirStatusProto.getIsDeleted(),
sdirStatusProto.getParentFullpath().toByteArray()); sdirStatusProto.getParentFullpath().toByteArray());
} }
@ -2425,6 +2426,7 @@ public static HdfsProtos.SnapshotStatusProto convert(SnapshotStatus status) {
.newBuilder() .newBuilder()
.setSnapshotID(status.getSnapshotID()) .setSnapshotID(status.getSnapshotID())
.setParentFullpath(parentFullPathBytes) .setParentFullpath(parentFullPathBytes)
.setIsDeleted(status.isDeleted())
.setDirStatus(fs); .setDirStatus(fs);
return builder.build(); return builder.build();
} }

View File

@ -574,6 +574,7 @@ message SnapshotStatusProto {
// Fields specific for snapshot directory // Fields specific for snapshot directory
required uint32 snapshotID = 2; required uint32 snapshotID = 2;
required bytes parent_fullpath = 3; required bytes parent_fullpath = 3;
required bool isDeleted = 4;
} }

View File

@ -599,7 +599,8 @@ public SnapshotStatus[] getSnapshotListing(INodesInPath iip)
// It is expensive to build the snapshot tree for the directory // It is expensive to build the snapshot tree for the directory
// and determine the child count. // and determine the child count.
dir.getChildrenNum(Snapshot.CURRENT_STATE_ID), dir.getChildrenNum(Snapshot.CURRENT_STATE_ID),
s.getId(), DFSUtil.string2Bytes(dir.getParent().getFullPathName())); s.getId(), s.getRoot().isMarkedAsDeleted(),
DFSUtil.string2Bytes(dir.getParent().getFullPathName()));
} }
return statuses; return statuses;

View File

@ -30,7 +30,10 @@
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.apache.hadoop.hdfs.server.namenode.snapshot.SnapshotManager.
DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
@ -51,6 +54,7 @@ public class TestListSnapshot {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
conf = new Configuration(); conf = new Configuration();
conf.setBoolean(DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED, true);
cluster = new MiniDFSCluster.Builder(conf).numDataNodes(REPLICATION) cluster = new MiniDFSCluster.Builder(conf).numDataNodes(REPLICATION)
.build(); .build();
cluster.waitActive(); cluster.waitActive();
@ -128,7 +132,15 @@ public void testListSnapshot() throws Exception {
snapshotStatuses[2].getFullPath()); snapshotStatuses[2].getFullPath());
hdfs.deleteSnapshot(dir1, "s2"); hdfs.deleteSnapshot(dir1, "s2");
snapshotStatuses = hdfs.getSnapshotListing(dir1); snapshotStatuses = hdfs.getSnapshotListing(dir1);
// There are now 2 snapshots for dir1 // There are now 2 active snapshots for dir1 and one is marked deleted
assertEquals(3, snapshotStatuses.length);
assertTrue(snapshotStatuses[2].isDeleted());
assertFalse(snapshotStatuses[1].isDeleted());
assertFalse(snapshotStatuses[0].isDeleted());
// delete the 1st snapshot
hdfs.deleteSnapshot(dir1, "s0");
snapshotStatuses = hdfs.getSnapshotListing(dir1);
// There are now 2 snapshots now as the 1st one is deleted in order
assertEquals(2, snapshotStatuses.length); assertEquals(2, snapshotStatuses.length);
} }
} }