Skip to content

Commit cfa9cfe

Browse files
authored
HDDS-12787. Make expired key move to trash configurable (#9594)
1 parent dd04f4b commit cfa9cfe

4 files changed

Lines changed: 62 additions & 1 deletion

File tree

hadoop-hdds/common/src/main/resources/ozone-default.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4915,6 +4915,15 @@
49154915
<tag>OZONE</tag>
49164916
<description>It specifies whether to enable lifecycle management service.</description>
49174917
</property>
4918+
4919+
<property>
4920+
<name>ozone.lifecycle.service.move.to.trash.enabled</name>
4921+
<value>true</value>
4922+
<tag>OZONE</tag>
4923+
<description>When enabled KeyLifecycleService will move expired keys/dirs to trash if trash is available.
4924+
When disabled, it will delete them directly.
4925+
</description>
4926+
</property>
49184927
<property>
49194928
<name>ozone.lifecycle.service.delete.batch-size</name>
49204929
<value>1000</value>

hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/OMConfigKeys.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,11 @@ public final class OMConfigKeys {
188188
"ozone.lifecycle.service.delete.cached.directory.max-count";
189189
public static final long OZONE_KEY_LIFECYCLE_SERVICE_DELETE_CACHED_DIRECTORY_MAX_COUNT_DEFAULT = 1000000;
190190

191+
public static final String OZONE_KEY_LIFECYCLE_SERVICE_MOVE_TO_TRASH_ENABLED =
192+
"ozone.lifecycle.service.move.to.trash.enabled";
193+
public static final boolean
194+
OZONE_KEY_LIFECYCLE_SERVICE_MOVE_TO_TRASH_ENABLED_DEFAULT = true;
195+
191196
/**
192197
* OM Ratis related configurations.
193198
*/

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/service/KeyLifecycleService.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_KEY_LIFECYCLE_SERVICE_DELETE_CACHED_DIRECTORY_MAX_COUNT_DEFAULT;
2727
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_KEY_LIFECYCLE_SERVICE_ENABLED;
2828
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_KEY_LIFECYCLE_SERVICE_ENABLED_DEFAULT;
29+
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_KEY_LIFECYCLE_SERVICE_MOVE_TO_TRASH_ENABLED;
30+
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_KEY_LIFECYCLE_SERVICE_MOVE_TO_TRASH_ENABLED_DEFAULT;
2931
import static org.apache.hadoop.ozone.om.helpers.BucketLayout.OBJECT_STORE;
3032

3133
import com.google.common.annotations.VisibleForTesting;
@@ -109,6 +111,7 @@ public class KeyLifecycleService extends BackgroundService {
109111
private long cachedDirMaxCount;
110112
private final AtomicBoolean suspended;
111113
private final AtomicBoolean isServiceEnabled;
114+
private final AtomicBoolean moveToTrashEnabled;
112115
private KeyLifecycleServiceMetrics metrics;
113116
// A set of bucket name that have LifecycleActionTask scheduled
114117
private final ConcurrentHashMap<String, LifecycleActionTask> inFlight;
@@ -137,6 +140,8 @@ public KeyLifecycleService(OzoneManager ozoneManager,
137140
this.metrics = KeyLifecycleServiceMetrics.create();
138141
this.isServiceEnabled = new AtomicBoolean(conf.getBoolean(OZONE_KEY_LIFECYCLE_SERVICE_ENABLED,
139142
OZONE_KEY_LIFECYCLE_SERVICE_ENABLED_DEFAULT));
143+
this.moveToTrashEnabled = new AtomicBoolean(conf.getBoolean(OZONE_KEY_LIFECYCLE_SERVICE_MOVE_TO_TRASH_ENABLED,
144+
OZONE_KEY_LIFECYCLE_SERVICE_MOVE_TO_TRASH_ENABLED_DEFAULT));
140145
this.inFlight = new ConcurrentHashMap();
141146
this.omMetadataManager = ozoneManager.getMetadataManager();
142147
int limit = (int) conf.getStorageSize(
@@ -812,7 +817,7 @@ private void onSuccess(String bucketName) {
812817
}
813818

814819
private void handleAndClearFullList(OmBucketInfo bucket, LimitedExpiredObjectList keysList, boolean dir) {
815-
if (bucket.getBucketLayout() != OBJECT_STORE && ozoneTrash != null) {
820+
if (moveToTrashEnabled.get() && bucket.getBucketLayout() != OBJECT_STORE && ozoneTrash != null) {
816821
moveToTrash(bucket, keysList, dir);
817822
} else {
818823
sendDeleteKeysRequestAndClearList(bucket.getVolumeName(), bucket.getBucketName(), keysList, dir);
@@ -1082,6 +1087,11 @@ public void setOzoneTrash(OzoneTrash ozoneTrash) {
10821087
this.ozoneTrash = ozoneTrash;
10831088
}
10841089

1090+
@VisibleForTesting
1091+
public void setMoveToTrashEnabled(boolean enabled) {
1092+
this.moveToTrashEnabled.set(enabled);
1093+
}
1094+
10851095
/**
10861096
* An in-memory list with limited size to hold expired object infos, including object name and current update ID.
10871097
*/

hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/service/TestKeyLifecycleService.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ void setup(@TempDir File testDir) throws Exception {
214214
@AfterEach
215215
void resume() {
216216
keyLifecycleService.setOzoneTrash(null);
217+
keyLifecycleService.setMoveToTrashEnabled(true);
217218
}
218219

219220
@AfterAll
@@ -1578,6 +1579,42 @@ void testGetLifecycleServiceStatus() throws Exception {
15781579

15791580
deleteLifecyclePolicy(volumeName, bucketName);
15801581
}
1582+
1583+
@Test
1584+
void testDisableMoveToTrashDeletesDirectly() throws Exception {
1585+
final String volumeName = getTestName();
1586+
final String bucketName = uniqueObjectName("bucket");
1587+
final String prefix = "key";
1588+
long initialDeletedKeyCount = getDeletedKeyCount();
1589+
long initialKeyCount = getKeyCount(FILE_SYSTEM_OPTIMIZED);
1590+
long initialRenamedKeyCount = metrics.getNumKeyRenamed().value();
1591+
1592+
// Create keys
1593+
createKeys(volumeName, bucketName, FILE_SYSTEM_OPTIMIZED, KEY_COUNT, 1, prefix, null);
1594+
Thread.sleep(SERVICE_INTERVAL);
1595+
GenericTestUtils.waitFor(() -> getKeyCount(FILE_SYSTEM_OPTIMIZED) - initialKeyCount == KEY_COUNT,
1596+
WAIT_CHECK_INTERVAL, 1000);
1597+
1598+
// Make trash available, but disable move.to.trash in KeyLifecycleService.
1599+
keyLifecycleService.setMoveToTrashEnabled(false);
1600+
final float trashInterval = 0.5f; // 30 seconds
1601+
conf.setFloat(FS_TRASH_INTERVAL_KEY, trashInterval);
1602+
FileSystem fs = SecurityUtil.doAsLoginUser(
1603+
(PrivilegedExceptionAction<FileSystem>)
1604+
() -> new TrashOzoneFileSystem(om));
1605+
keyLifecycleService.setOzoneTrash(new OzoneTrash(fs, conf, om));
1606+
1607+
// Expire keys
1608+
ZonedDateTime date = ZonedDateTime.now(ZoneOffset.UTC).plusSeconds(EXPIRE_SECONDS);
1609+
createLifecyclePolicy(volumeName, bucketName, FILE_SYSTEM_OPTIMIZED, "", null, date.toString(), true);
1610+
1611+
// With move.to.trash disabled, keys should be deleted directly (not renamed).
1612+
GenericTestUtils.waitFor(() ->
1613+
(getDeletedKeyCount() - initialDeletedKeyCount) == KEY_COUNT, WAIT_CHECK_INTERVAL, 10000);
1614+
assertEquals(initialRenamedKeyCount, metrics.getNumKeyRenamed().value());
1615+
assertEquals(0, getKeyCount(FILE_SYSTEM_OPTIMIZED) - initialKeyCount);
1616+
deleteLifecyclePolicy(volumeName, bucketName);
1617+
}
15811618
}
15821619

15831620
/**

0 commit comments

Comments
 (0)