You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by ra...@apache.org on 2021/04/09 06:41:25 UTC

[ozone] branch HDDS-2939 updated: HDDS-5042. [FSO] Improve KeyDeletingService to cleanup FSO files (#2128)

This is an automated email from the ASF dual-hosted git repository.

rakeshr pushed a commit to branch HDDS-2939
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-2939 by this push:
     new aa0abab  HDDS-5042. [FSO] Improve KeyDeletingService to cleanup FSO files (#2128)
aa0abab is described below

commit aa0ababdd07e010f622f92fcff1a166f54ad9699
Author: Sadanand Shenoy <sa...@gmail.com>
AuthorDate: Fri Apr 9 12:11:05 2021 +0530

    HDDS-5042. [FSO] Improve KeyDeletingService to cleanup FSO files (#2128)
---
 .../TestDirectoryDeletingServiceWithFSOBucket.java | 116 +++++++++++++++++++++
 .../hadoop/ozone/om/DirectoryDeletingService.java  |   2 +-
 .../response/key/AbstractOMKeyDeleteResponse.java  |  44 ++++++++
 .../om/response/key/OMKeyDeleteResponseV1.java     |  13 ++-
 .../om/response/key/OMPathsPurgeResponseV1.java    |   6 +-
 .../om/response/key/TestOMKeyDeleteResponse.java   |  11 +-
 6 files changed, 185 insertions(+), 7 deletions(-)

diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestDirectoryDeletingServiceWithFSOBucket.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestDirectoryDeletingServiceWithFSOBucket.java
index df2e47b..acbdfaf 100644
--- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestDirectoryDeletingServiceWithFSOBucket.java
+++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestDirectoryDeletingServiceWithFSOBucket.java
@@ -20,6 +20,7 @@ package org.apache.hadoop.fs.ozone;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
+import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.fs.FileStatus;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
@@ -31,9 +32,11 @@ import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.TestDataUtil;
 import org.apache.hadoop.ozone.client.OzoneBucket;
 import org.apache.hadoop.ozone.om.DirectoryDeletingService;
+import org.apache.hadoop.ozone.om.KeyDeletingService;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
 import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
+import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
 import org.apache.hadoop.ozone.om.request.TestOMRequestUtils;
 import org.apache.hadoop.test.GenericTestUtils;
 import org.junit.After;
@@ -315,4 +318,117 @@ public class TestDirectoryDeletingServiceWithFSOBucket {
     }
   }
 
+  @Test
+  public void testDeleteSubFiles() throws Exception {
+
+    Table<String, OmKeyInfo> deletedDirTable =
+        cluster.getOzoneManager().getMetadataManager().getDeletedDirTable();
+    Table<String, OmKeyInfo> keyTable =
+        cluster.getOzoneManager().getMetadataManager().getKeyTable();
+    Table<String, OmDirectoryInfo> dirTable =
+        cluster.getOzoneManager().getMetadataManager().getDirectoryTable();
+    Table<String, RepeatedOmKeyInfo> deletedKeyTable =
+        cluster.getOzoneManager().getMetadataManager().getDeletedTable();
+
+    Path root = new Path("/rootDir2");
+    // Create  parent dir from root.
+    fs.mkdirs(root);
+
+    // Added 10 sub files inside root dir
+    for (int i = 0; i<10; i++) {
+      Path path = new Path(root, "testKey" + i);
+      try (FSDataOutputStream stream = fs.create(path)) {
+        stream.write(1);
+      }
+    }
+
+    KeyDeletingService keyDeletingService =
+        (KeyDeletingService) cluster.getOzoneManager().getKeyManager()
+            .getDeletingService();
+
+    // Before delete
+    assertTableRowCount(deletedDirTable, 0);
+    assertTableRowCount(keyTable, 10);
+    assertTableRowCount(dirTable, 1);
+    long prevDeletedKeyCount = keyDeletingService.getDeletedKeyCount().get();
+
+    fs.delete(root, true);
+
+    DirectoryDeletingService dirDeletingService =
+        (DirectoryDeletingService) cluster.getOzoneManager().getKeyManager()
+            .getDirDeletingService();
+
+    // After delete
+    assertTableRowCount(keyTable, 0);
+    assertTableRowCount(dirTable, 0);
+
+    // Eventually keys would get cleaned up from deletedTables too
+    assertTableRowCount(deletedDirTable, 0);
+    assertTableRowCount(deletedKeyTable, 0);
+
+    assertSubPathsCount(dirDeletingService.getMovedFilesCount(), 10);
+    assertSubPathsCount(dirDeletingService.getDeletedDirsCount(), 1);
+    // verify whether KeyDeletingService has purged the keys
+    long currentDeletedKeyCount = keyDeletingService.getDeletedKeyCount().get();
+    Assert.assertEquals(currentDeletedKeyCount, prevDeletedKeyCount + 10);
+  }
+
+  @Test
+  public void testDeleteFiles() throws Exception {
+
+    Table<String, OmKeyInfo> deletedDirTable =
+        cluster.getOzoneManager().getMetadataManager().getDeletedDirTable();
+    Table<String, OmKeyInfo> keyTable =
+        cluster.getOzoneManager().getMetadataManager().getKeyTable();
+    Table<String, OmDirectoryInfo> dirTable =
+        cluster.getOzoneManager().getMetadataManager().getDirectoryTable();
+    Table<String, RepeatedOmKeyInfo> deletedKeyTable =
+        cluster.getOzoneManager().getMetadataManager().getDeletedTable();
+
+    Path root = new Path("/rootDir2");
+    // Create  parent dir from root.
+    fs.mkdirs(root);
+
+    // Added 10 sub files inside root dir
+    for (int i = 0; i<10; i++) {
+      Path path = new Path(root, "testKey" + i);
+      try (FSDataOutputStream stream = fs.create(path)) {
+        stream.write(1);
+      }
+    }
+
+    KeyDeletingService keyDeletingService =
+        (KeyDeletingService) cluster.getOzoneManager().getKeyManager()
+            .getDeletingService();
+
+    // Before delete
+    assertTableRowCount(deletedDirTable, 0);
+    assertTableRowCount(keyTable, 10);
+    assertTableRowCount(dirTable, 1);
+    long prevDeletedKeyCount = keyDeletingService.getDeletedKeyCount().get();
+
+    for (int i = 0; i<10; i++) {
+      Path path = new Path(root, "testKey" + i);
+      fs.delete(path, true);
+    }
+
+    DirectoryDeletingService dirDeletingService =
+        (DirectoryDeletingService) cluster.getOzoneManager().getKeyManager()
+            .getDirDeletingService();
+
+
+    // After delete
+    assertTableRowCount(keyTable, 0);
+    assertTableRowCount(dirTable, 1);
+
+    // Eventually keys would get cleaned up from deletedTables too
+    assertTableRowCount(deletedDirTable, 0);
+    assertTableRowCount(deletedKeyTable, 0);
+
+    assertSubPathsCount(dirDeletingService.getMovedFilesCount(), 0);
+    assertSubPathsCount(dirDeletingService.getDeletedDirsCount(), 0);
+    // verify whether KeyDeletingService has purged the keys
+    long currentDeletedKeyCount = keyDeletingService.getDeletedKeyCount().get();
+    Assert.assertEquals(currentDeletedKeyCount, prevDeletedKeyCount + 10);
+  }
 }
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/DirectoryDeletingService.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/DirectoryDeletingService.java
index bb33722..a8d66cd 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/DirectoryDeletingService.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/DirectoryDeletingService.java
@@ -239,7 +239,7 @@ public class DirectoryDeletingService extends BackgroundService {
     }
     for (OmKeyInfo purgeFile : purgeDeletedFiles) {
       purgePathsRequest.addDeletedSubFiles(
-          purgeFile.getProtobuf(CURRENT_VERSION));
+          purgeFile.getProtobuf(true, CURRENT_VERSION));
     }
 
     // Add these directories to deletedDirTable, so that its sub-paths will be
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/AbstractOMKeyDeleteResponse.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/AbstractOMKeyDeleteResponse.java
index 9392f7e..51118c3 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/AbstractOMKeyDeleteResponse.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/AbstractOMKeyDeleteResponse.java
@@ -100,6 +100,50 @@ public abstract class AbstractOMKeyDeleteResponse extends OMClientResponse {
     }
   }
 
+  /**
+   *  This method is used for FSO file deletes.
+   *  Since a common deletedTable is used ,it requires to add  key in the
+   *  full format (vol/buck/key). This method deletes the key from
+   *  file table (which is in prefix format) and adds the fullKey
+   *  into the deletedTable
+   * @param keyName     (format: objectId/key)
+   * @param fullKeyName (format: vol/buck/key)
+   * @param omKeyInfo
+   * @throws IOException
+   */
+  protected void addDeletionToBatch(
+      OMMetadataManager omMetadataManager,
+      BatchOperation batchOperation,
+      Table<String, ?> fromTable,
+      String keyName, String fullKeyName,
+      OmKeyInfo omKeyInfo) throws IOException {
+
+    // For OmResponse with failure, this should do nothing. This method is
+    // not called in failure scenario in OM code.
+    fromTable.deleteWithBatch(batchOperation, keyName);
+
+    // If Key is not empty add this to delete table.
+    if (!isKeyEmpty(omKeyInfo)) {
+      // If a deleted key is put in the table where a key with the same
+      // name already exists, then the old deleted key information would be
+      // lost. To avoid this, first check if a key with same name exists.
+      // deletedTable in OM Metadata stores <KeyName, RepeatedOMKeyInfo>.
+      // The RepeatedOmKeyInfo is the structure that allows us to store a
+      // list of OmKeyInfo that can be tied to same key name. For a keyName
+      // if RepeatedOMKeyInfo structure is null, we create a new instance,
+      // if it is not null, then we simply add to the list and store this
+      // instance in deletedTable.
+      RepeatedOmKeyInfo repeatedOmKeyInfo =
+          omMetadataManager.getDeletedTable().get(fullKeyName);
+      repeatedOmKeyInfo = OmUtils.prepareKeyForDelete(
+          omKeyInfo, repeatedOmKeyInfo, omKeyInfo.getUpdateID(),
+          isRatisEnabled);
+      omMetadataManager.getDeletedTable().putWithBatch(
+          batchOperation, fullKeyName, repeatedOmKeyInfo);
+    }
+  }
+
+
   @Override
   public abstract void addToDBBatch(OMMetadataManager omMetadataManager,
         BatchOperation batchOperation) throws IOException;
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMKeyDeleteResponseV1.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMKeyDeleteResponseV1.java
index 69e87df..afcdd76 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMKeyDeleteResponseV1.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMKeyDeleteResponseV1.java
@@ -29,6 +29,7 @@ import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRespo
 import javax.annotation.Nonnull;
 import java.io.IOException;
 
+import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.DELETED_DIR_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.DELETED_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.DIRECTORY_TABLE;
 import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.FILE_TABLE;
@@ -36,7 +37,8 @@ import static org.apache.hadoop.ozone.om.OmMetadataManagerImpl.FILE_TABLE;
 /**
  * Response for DeleteKey request.
  */
-@CleanupTableInfo(cleanupTables = {FILE_TABLE, DIRECTORY_TABLE, DELETED_TABLE})
+@CleanupTableInfo(cleanupTables = {FILE_TABLE, DIRECTORY_TABLE,
+    DELETED_TABLE, DELETED_DIR_TABLE})
 public class OMKeyDeleteResponseV1 extends OMKeyDeleteResponse {
 
   private boolean isDeleteDirectory;
@@ -79,8 +81,15 @@ public class OMKeyDeleteResponseV1 extends OMKeyDeleteResponse {
           batchOperation, ozoneDbKey, omKeyInfo);
     } else {
       Table<String, OmKeyInfo> keyTable = omMetadataManager.getKeyTable();
+      OmKeyInfo omKeyInfo = getOmKeyInfo();
+      // Sets full absolute key name to OmKeyInfo, which is
+      // required for moving the sub-files to KeyDeletionService.
+      omKeyInfo.setKeyName(keyName);
+      String deletedKey = omMetadataManager
+          .getOzoneKey(omKeyInfo.getVolumeName(), omKeyInfo.getBucketName(),
+              omKeyInfo.getKeyName());
       addDeletionToBatch(omMetadataManager, batchOperation, keyTable,
-              ozoneDbKey, getOmKeyInfo());
+          ozoneDbKey, deletedKey, omKeyInfo);
     }
 
     // update bucket usedBytes.
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMPathsPurgeResponseV1.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMPathsPurgeResponseV1.java
index b6f5299..714024a 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMPathsPurgeResponseV1.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/response/key/OMPathsPurgeResponseV1.java
@@ -112,8 +112,12 @@ public class OMPathsPurgeResponseV1 extends OMClientResponse {
       repeatedOmKeyInfo = OmUtils.prepareKeyForDelete(keyInfo,
           repeatedOmKeyInfo, keyInfo.getUpdateID(), isRatisEnabled);
 
+      String deletedKey = omMetadataManager
+          .getOzoneKey(keyInfo.getVolumeName(), keyInfo.getBucketName(),
+              keyInfo.getKeyName());
+
       omMetadataManager.getDeletedTable().putWithBatch(batchOperation,
-          keyInfo.getPath(), repeatedOmKeyInfo);
+          deletedKey, repeatedOmKeyInfo);
 
     }
   }
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/key/TestOMKeyDeleteResponse.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/key/TestOMKeyDeleteResponse.java
index 712a4ec..c68ff41 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/key/TestOMKeyDeleteResponse.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/key/TestOMKeyDeleteResponse.java
@@ -69,10 +69,13 @@ public class TestOMKeyDeleteResponse extends TestOMKeyResponse {
 
     Assert.assertFalse(omMetadataManager.getKeyTable().isExist(ozoneKey));
 
+    String deletedKey = omMetadataManager.getOzoneKey(volumeName, bucketName,
+        keyName);
+
     // As default key entry does not have any blocks, it should not be in
     // deletedKeyTable.
     Assert.assertFalse(omMetadataManager.getDeletedTable().isExist(
-        ozoneKey));
+        deletedKey));
   }
 
   @Test
@@ -124,9 +127,11 @@ public class TestOMKeyDeleteResponse extends TestOMKeyResponse {
 
     Assert.assertFalse(omMetadataManager.getKeyTable().isExist(ozoneKey));
 
+    String deletedKey = omMetadataManager.getOzoneKey(volumeName, bucketName,
+        keyName);
+
     // Key has blocks, it should not be in deletedKeyTable.
-    Assert.assertTrue(omMetadataManager.getDeletedTable().isExist(
-        ozoneKey));
+    Assert.assertTrue(omMetadataManager.getDeletedTable().isExist(deletedKey));
   }
 
 

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org