in hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/service/KeyDeletingService.java [254:464]
private void processSnapshotDeepClean(int delCount)
throws IOException {
OmSnapshotManager omSnapshotManager =
getOzoneManager().getOmSnapshotManager();
OmMetadataManagerImpl metadataManager = (OmMetadataManagerImpl)
getOzoneManager().getMetadataManager();
SnapshotChainManager snapChainManager = metadataManager
.getSnapshotChainManager();
Table<String, SnapshotInfo> snapshotInfoTable =
getOzoneManager().getMetadataManager().getSnapshotInfoTable();
List<String> deepCleanedSnapshots = new ArrayList<>();
try (TableIterator<String, ? extends Table.KeyValue
<String, SnapshotInfo>> iterator = snapshotInfoTable.iterator()) {
while (delCount < keyLimitPerTask && iterator.hasNext()) {
List<BlockGroup> keysToPurge = new ArrayList<>();
HashMap<String, RepeatedOmKeyInfo> keysToModify = new HashMap<>();
SnapshotInfo currSnapInfo = snapshotInfoTable.get(iterator.next().getKey());
// Deep clean only on active snapshot. Deleted Snapshots will be
// cleaned up by SnapshotDeletingService.
if (currSnapInfo == null || currSnapInfo.getSnapshotStatus() != SNAPSHOT_ACTIVE ||
currSnapInfo.getDeepClean()) {
continue;
}
SnapshotInfo prevSnapInfo = SnapshotUtils.getPreviousSnapshot(getOzoneManager(), snapChainManager,
currSnapInfo);
if (prevSnapInfo != null &&
(prevSnapInfo.getSnapshotStatus() != SnapshotInfo.SnapshotStatus.SNAPSHOT_ACTIVE ||
!OmSnapshotManager.areSnapshotChangesFlushedToDB(getOzoneManager().getMetadataManager(),
prevSnapInfo))) {
continue;
}
try (ReferenceCounted<OmSnapshot>
rcCurrOmSnapshot = omSnapshotManager.getSnapshot(
currSnapInfo.getVolumeName(),
currSnapInfo.getBucketName(),
currSnapInfo.getName())) {
OmSnapshot currOmSnapshot = rcCurrOmSnapshot.get();
Table<String, RepeatedOmKeyInfo> snapDeletedTable =
currOmSnapshot.getMetadataManager().getDeletedTable();
Table<String, String> snapRenamedTable =
currOmSnapshot.getMetadataManager().getSnapshotRenamedTable();
long volumeId = metadataManager.getVolumeId(
currSnapInfo.getVolumeName());
// Get bucketInfo for the snapshot bucket to get bucket layout.
String dbBucketKey = metadataManager.getBucketKey(
currSnapInfo.getVolumeName(), currSnapInfo.getBucketName());
OmBucketInfo bucketInfo = metadataManager.getBucketTable()
.get(dbBucketKey);
if (bucketInfo == null) {
throw new IllegalStateException("Bucket " + "/" + currSnapInfo
.getVolumeName() + "/" + currSnapInfo.getBucketName() +
" is not found. BucketInfo should not be null for" +
" snapshotted bucket. The OM is in unexpected state.");
}
String snapshotBucketKey = dbBucketKey + OzoneConsts.OM_KEY_PREFIX;
SnapshotInfo previousSnapshot = SnapshotUtils.getPreviousSnapshot(getOzoneManager(), snapChainManager,
currSnapInfo);
SnapshotInfo previousToPrevSnapshot = null;
if (previousSnapshot != null) {
previousToPrevSnapshot = SnapshotUtils.getPreviousSnapshot(getOzoneManager(), snapChainManager,
previousSnapshot);
}
Table<String, OmKeyInfo> previousKeyTable = null;
Table<String, String> prevRenamedTable = null;
ReferenceCounted<OmSnapshot> rcPrevOmSnapshot = null;
// Split RepeatedOmKeyInfo and update current snapshot
// deletedKeyTable and next snapshot deletedKeyTable.
if (previousSnapshot != null) {
rcPrevOmSnapshot = omSnapshotManager.getSnapshot(
previousSnapshot.getVolumeName(),
previousSnapshot.getBucketName(),
previousSnapshot.getName());
OmSnapshot omPreviousSnapshot = rcPrevOmSnapshot.get();
previousKeyTable = omPreviousSnapshot.getMetadataManager()
.getKeyTable(bucketInfo.getBucketLayout());
prevRenamedTable = omPreviousSnapshot
.getMetadataManager().getSnapshotRenamedTable();
}
Table<String, OmKeyInfo> previousToPrevKeyTable = null;
ReferenceCounted<OmSnapshot> rcPrevToPrevOmSnapshot = null;
if (previousToPrevSnapshot != null) {
rcPrevToPrevOmSnapshot = omSnapshotManager.getSnapshot(
previousToPrevSnapshot.getVolumeName(),
previousToPrevSnapshot.getBucketName(),
previousToPrevSnapshot.getName());
OmSnapshot omPreviousToPrevSnapshot = rcPrevToPrevOmSnapshot.get();
previousToPrevKeyTable = omPreviousToPrevSnapshot
.getMetadataManager()
.getKeyTable(bucketInfo.getBucketLayout());
}
try (TableIterator<String, ? extends Table.KeyValue<String,
RepeatedOmKeyInfo>> deletedIterator = snapDeletedTable
.iterator()) {
String lastKeyInCurrentRun = null;
String deletedTableSeek = snapshotSeekMap.getOrDefault(
currSnapInfo.getTableKey(), snapshotBucketKey);
deletedIterator.seek(deletedTableSeek);
// To avoid processing the last key from the previous
// run again.
if (!deletedTableSeek.equals(snapshotBucketKey) &&
deletedIterator.hasNext()) {
deletedIterator.next();
}
while (deletedIterator.hasNext() && delCount < keyLimitPerTask) {
Table.KeyValue<String, RepeatedOmKeyInfo>
deletedKeyValue = deletedIterator.next();
String deletedKey = deletedKeyValue.getKey();
lastKeyInCurrentRun = deletedKey;
// Exit if it is out of the bucket scope.
if (!deletedKey.startsWith(snapshotBucketKey)) {
break;
}
RepeatedOmKeyInfo repeatedOmKeyInfo =
deletedKeyValue.getValue();
List<BlockGroup> blockGroupList = new ArrayList<>();
RepeatedOmKeyInfo newRepeatedOmKeyInfo =
new RepeatedOmKeyInfo();
for (OmKeyInfo keyInfo : repeatedOmKeyInfo.getOmKeyInfoList()) {
if (previousSnapshot != null) {
// Calculates the exclusive size for the previous
// snapshot. See Java Doc for more info.
calculateExclusiveSize(previousSnapshot,
previousToPrevSnapshot, keyInfo, bucketInfo, volumeId,
snapRenamedTable, previousKeyTable, prevRenamedTable,
previousToPrevKeyTable, exclusiveSizeMap,
exclusiveReplicatedSizeMap);
}
if (isKeyReclaimable(previousKeyTable, snapRenamedTable,
keyInfo, bucketInfo, volumeId, null)) {
List<BlockGroup> blocksForKeyDelete = currOmSnapshot
.getMetadataManager()
.getBlocksForKeyDelete(deletedKey);
if (blocksForKeyDelete != null) {
blockGroupList.addAll(blocksForKeyDelete);
}
delCount++;
} else {
newRepeatedOmKeyInfo.addOmKeyInfo(keyInfo);
}
}
if (!newRepeatedOmKeyInfo.getOmKeyInfoList().isEmpty() &&
newRepeatedOmKeyInfo.getOmKeyInfoList().size() !=
repeatedOmKeyInfo.getOmKeyInfoList().size()) {
keysToModify.put(deletedKey, newRepeatedOmKeyInfo);
}
if (newRepeatedOmKeyInfo.getOmKeyInfoList().size() !=
repeatedOmKeyInfo.getOmKeyInfoList().size()) {
keysToPurge.addAll(blockGroupList);
}
}
if (delCount < keyLimitPerTask) {
// Deep clean is completed, we can update the SnapInfo.
deepCleanedSnapshots.add(currSnapInfo.getTableKey());
// exclusiveSizeList contains check is used to prevent
// case where there is no entry in deletedTable, this
// will throw NPE when we submit request.
if (previousSnapshot != null && exclusiveSizeMap
.containsKey(previousSnapshot.getTableKey())) {
completedExclusiveSizeSet.add(
previousSnapshot.getTableKey());
}
snapshotSeekMap.remove(currSnapInfo.getTableKey());
} else {
// There are keys that still needs processing
// we can continue from it in the next iteration
if (lastKeyInCurrentRun != null) {
snapshotSeekMap.put(currSnapInfo.getTableKey(),
lastKeyInCurrentRun);
}
}
if (!keysToPurge.isEmpty()) {
processKeyDeletes(keysToPurge, currOmSnapshot.getKeyManager(),
keysToModify, currSnapInfo.getTableKey(),
Optional.ofNullable(previousSnapshot).map(SnapshotInfo::getSnapshotId).orElse(null));
}
} finally {
IOUtils.closeQuietly(rcPrevOmSnapshot, rcPrevToPrevOmSnapshot);
}
}
}
}
updateDeepCleanedSnapshots(deepCleanedSnapshots);
updateSnapshotExclusiveSize();
}