in hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataManagerImpl.java [1324:1457]
public PendingKeysDeletion getPendingDeletionKeys(final int keyCount,
OmSnapshotManager omSnapshotManager)
throws IOException {
List<BlockGroup> keyBlocksList = Lists.newArrayList();
HashMap<String, RepeatedOmKeyInfo> keysToModify = new HashMap<>();
try (TableIterator<String, ? extends KeyValue<String, RepeatedOmKeyInfo>>
keyIter = getDeletedTable().iterator()) {
int currentCount = 0;
while (keyIter.hasNext() && currentCount < keyCount) {
RepeatedOmKeyInfo notReclaimableKeyInfo = new RepeatedOmKeyInfo();
KeyValue<String, RepeatedOmKeyInfo> kv = keyIter.next();
if (kv != null) {
List<BlockGroup> blockGroupList = Lists.newArrayList();
// Get volume name and bucket name
String[] keySplit = kv.getKey().split(OM_KEY_PREFIX);
String bucketKey = getBucketKey(keySplit[1], keySplit[2]);
OmBucketInfo bucketInfo = getBucketTable().get(bucketKey);
// If Bucket deleted bucketInfo would be null, thus making previous snapshot also null.
SnapshotInfo previousSnapshotInfo = bucketInfo == null ? null :
SnapshotUtils.getLatestSnapshotInfo(bucketInfo.getVolumeName(),
bucketInfo.getBucketName(), ozoneManager, snapshotChainManager);
// previous snapshot is not active or it has not been flushed to disk then don't process the key in this
// iteration.
if (previousSnapshotInfo != null &&
(previousSnapshotInfo.getSnapshotStatus() != SnapshotInfo.SnapshotStatus.SNAPSHOT_ACTIVE ||
!OmSnapshotManager.areSnapshotChangesFlushedToDB(ozoneManager.getMetadataManager(),
previousSnapshotInfo))) {
continue;
}
// Get the latest snapshot in snapshot path.
try (ReferenceCounted<OmSnapshot> rcLatestSnapshot = previousSnapshotInfo == null ? null :
omSnapshotManager.getSnapshot(previousSnapshotInfo.getVolumeName(),
previousSnapshotInfo.getBucketName(), previousSnapshotInfo.getName())) {
// Multiple keys with the same path can be queued in one DB entry
RepeatedOmKeyInfo infoList = kv.getValue();
for (OmKeyInfo info : infoList.cloneOmKeyInfoList()) {
// Skip the key if it exists in the previous snapshot (of the same
// scope) as in this case its blocks should not be reclaimed
// If the last snapshot is deleted and the keys renamed in between
// the snapshots will be cleaned up by KDS. So we need to check
// in the renamedTable as well.
String dbRenameKey = getRenameKey(info.getVolumeName(),
info.getBucketName(), info.getObjectID());
if (rcLatestSnapshot != null) {
Table<String, OmKeyInfo> prevKeyTable =
rcLatestSnapshot.get()
.getMetadataManager()
.getKeyTable(bucketInfo.getBucketLayout());
Table<String, RepeatedOmKeyInfo> prevDeletedTable =
rcLatestSnapshot.get().getMetadataManager().getDeletedTable();
String prevKeyTableDBKey = getSnapshotRenamedTable()
.get(dbRenameKey);
String prevDelTableDBKey = getOzoneKey(info.getVolumeName(),
info.getBucketName(), info.getKeyName());
// format: /volName/bucketName/keyName/objId
prevDelTableDBKey = getOzoneDeletePathKey(info.getObjectID(),
prevDelTableDBKey);
if (prevKeyTableDBKey == null &&
bucketInfo.getBucketLayout().isFileSystemOptimized()) {
long volumeId = getVolumeId(info.getVolumeName());
prevKeyTableDBKey = getOzonePathKey(volumeId,
bucketInfo.getObjectID(),
info.getParentObjectID(),
info.getFileName());
} else if (prevKeyTableDBKey == null) {
prevKeyTableDBKey = getOzoneKey(info.getVolumeName(),
info.getBucketName(),
info.getKeyName());
}
OmKeyInfo omKeyInfo = prevKeyTable.get(prevKeyTableDBKey);
// When key is deleted it is no longer in keyTable, we also
// have to check deletedTable of previous snapshot
RepeatedOmKeyInfo delOmKeyInfo =
prevDeletedTable.get(prevDelTableDBKey);
if (versionExistsInPreviousSnapshot(omKeyInfo,
info, delOmKeyInfo)) {
// If the infoList size is 1, there is nothing to split.
// We either delete it or skip it.
if (!(infoList.getOmKeyInfoList().size() == 1)) {
notReclaimableKeyInfo.addOmKeyInfo(info);
}
continue;
}
}
// Add all blocks from all versions of the key to the deletion
// list
for (OmKeyLocationInfoGroup keyLocations :
info.getKeyLocationVersions()) {
List<BlockID> item = keyLocations.getLocationList().stream()
.map(b -> new BlockID(b.getContainerID(), b.getLocalID()))
.collect(Collectors.toList());
BlockGroup keyBlocks = BlockGroup.newBuilder()
.setKeyName(kv.getKey())
.addAllBlockIDs(item)
.build();
blockGroupList.add(keyBlocks);
}
currentCount++;
}
List<OmKeyInfo> notReclaimableKeyInfoList =
notReclaimableKeyInfo.getOmKeyInfoList();
// If Bucket deleted bucketInfo would be null, thus making previous snapshot also null.
SnapshotInfo newPreviousSnapshotInfo = bucketInfo == null ? null :
SnapshotUtils.getLatestSnapshotInfo(bucketInfo.getVolumeName(),
bucketInfo.getBucketName(), ozoneManager, snapshotChainManager);
// Check if the previous snapshot in the chain hasn't changed.
if (Objects.equals(Optional.ofNullable(newPreviousSnapshotInfo).map(SnapshotInfo::getSnapshotId),
Optional.ofNullable(previousSnapshotInfo).map(SnapshotInfo::getSnapshotId))) {
// If all the versions are not reclaimable, then do nothing.
if (!notReclaimableKeyInfoList.isEmpty() &&
notReclaimableKeyInfoList.size() !=
infoList.getOmKeyInfoList().size()) {
keysToModify.put(kv.getKey(), notReclaimableKeyInfo);
}
if (notReclaimableKeyInfoList.size() !=
infoList.getOmKeyInfoList().size()) {
keyBlocksList.addAll(blockGroupList);
}
}
}
}
}
}
return new PendingKeysDeletion(keyBlocksList, keysToModify);
}