From 9912b84743cbb75a9acac085fa0d7f2a5a8ce973 Mon Sep 17 00:00:00 2001
From: Siyao Meng <50227127+smengcl@users.noreply.github.com>
Date: Tue, 14 Jul 2026 12:56:59 -0700
Subject: [PATCH 1/4] HDDS-15860. Always rewrite live SSTs before snapshot
defrag ingestion
---
.../defrag/SnapshotDefragService.java | 28 ++-
.../defrag/TestSnapshotDefragService.java | 187 +++++++++++++++---
2 files changed, 172 insertions(+), 43 deletions(-)
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/defrag/SnapshotDefragService.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/defrag/SnapshotDefragService.java
index 4f018ed4641e..85b6ea2bfcb9 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/defrag/SnapshotDefragService.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/defrag/SnapshotDefragService.java
@@ -411,22 +411,18 @@ void performIncrementalDefragmentation(SnapshotInfo previousSnapshotInfo, Snapsh
for (Map.Entry> entry : tableGroupedDeltaFiles.entrySet()) {
String table = entry.getKey();
List deltaFiles = entry.getValue();
- Path fileToBeIngested;
- if (deltaFiles.size() == 1 && snapshotVersion > 0) {
- // If there is only one delta file for the table and the snapshot version is also not 0 then the same delta
- // file can reingested into the checkpointStore.
- fileToBeIngested = deltaFiles.get(0);
- } else {
- Table snapshotTable = snapshot.get().getMetadataManager().getStore()
- .getTable(table, StringCodec.get(), CodecBufferCodec.get(true));
- Table previousSnapshotTable = previousSnapshot.get().getMetadataManager().getStore()
- .getTable(table, StringCodec.get(), CodecBufferCodec.get(true));
- String tableBucketPrefix = bucketPrefixInfo.getTablePrefix(table);
- Pair spillResult = spillTableDiffIntoSstFile(deltaFiles, snapshotTable,
- previousSnapshotTable, tableBucketPrefix);
- fileToBeIngested = spillResult.getValue() ? spillResult.getLeft() : null;
- filesToBeDeleted.add(spillResult.getLeft());
- }
+ // Delta candidates are live RocksDB SSTs selected at file granularity,
+ // not valid external SSTs containing an exact bucket-level delta. Always
+ // rebuild the logical delta, even when there is only one candidate file.
+ Table snapshotTable = snapshot.get().getMetadataManager().getStore()
+ .getTable(table, StringCodec.get(), CodecBufferCodec.get(true));
+ Table previousSnapshotTable = previousSnapshot.get().getMetadataManager().getStore()
+ .getTable(table, StringCodec.get(), CodecBufferCodec.get(true));
+ String tableBucketPrefix = bucketPrefixInfo.getTablePrefix(table);
+ Pair spillResult = spillTableDiffIntoSstFile(deltaFiles, snapshotTable,
+ previousSnapshotTable, tableBucketPrefix);
+ Path fileToBeIngested = spillResult.getValue() ? spillResult.getLeft() : null;
+ filesToBeDeleted.add(spillResult.getLeft());
if (fileToBeIngested != null) {
if (!fileToBeIngested.toFile().exists()) {
throw new IOException("Delta file does not exist: " + fileToBeIngested);
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
index f93d95d6ac9e..dda0f7e2805b 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
@@ -52,10 +52,13 @@
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
+import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -82,9 +85,11 @@
import org.apache.hadoop.hdds.utils.db.CodecException;
import org.apache.hadoop.hdds.utils.db.DBCheckpoint;
import org.apache.hadoop.hdds.utils.db.DBStore;
+import org.apache.hadoop.hdds.utils.db.DBStoreBuilder;
import org.apache.hadoop.hdds.utils.db.InMemoryTestTable;
import org.apache.hadoop.hdds.utils.db.ManagedRawSSTFileReader;
import org.apache.hadoop.hdds.utils.db.RDBSstFileWriter;
+import org.apache.hadoop.hdds.utils.db.RDBStore;
import org.apache.hadoop.hdds.utils.db.RocksDBCheckpoint;
import org.apache.hadoop.hdds.utils.db.RocksDatabaseException;
import org.apache.hadoop.hdds.utils.db.SstFileSetReader;
@@ -122,6 +127,7 @@
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.InOrder;
@@ -130,12 +136,18 @@
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.rocksdb.LiveFileMetaData;
/**
* Unit tests for SnapshotDefragService.
*/
public class TestSnapshotDefragService {
+ private enum LiveSstType {
+ DB_GENERATED,
+ PREVIOUSLY_INGESTED
+ }
+
@Mock
private OzoneManager ozoneManager;
@@ -224,6 +236,71 @@ private String getFromCodecBuffer(CodecBuffer buffer) {
return StringCodec.get().fromCodecBuffer(buffer);
}
+ private void putString(Table table, String key,
+ String value) throws RocksDatabaseException, CodecException {
+ table.put(key, StringCodec.get().toDirectCodecBuffer(value));
+ }
+
+ private DBStore createDBStore(String name, String tableName)
+ throws RocksDatabaseException {
+ return DBStoreBuilder.newBuilder(configuration)
+ .setName(name)
+ .setPath(tempDir)
+ .addTable(tableName)
+ .build();
+ }
+
+ private Path createLiveSstDelta(DBStore sourceStore, String tableName,
+ String key, LiveSstType liveSstType) throws Exception {
+ Table sourceTable = sourceStore.getTable(
+ tableName, StringCodec.get(), CodecBufferCodec.get(true));
+ putString(sourceTable, key, "source-value");
+ sourceStore.flushDB();
+
+ if (liveSstType == LiveSstType.PREVIOUSLY_INGESTED) {
+ File externalFile = tempDir.resolve("external-" + UUID.randomUUID()
+ + ".sst").toFile();
+ try (RDBSstFileWriter writer = new RDBSstFileWriter(externalFile);
+ CodecBuffer keyBuffer = StringCodec.get().toDirectCodecBuffer(key);
+ CodecBuffer valueBuffer = StringCodec.get()
+ .toDirectCodecBuffer("ingested-value")) {
+ writer.put(keyBuffer, valueBuffer);
+ }
+ sourceTable.loadFromFile(externalFile);
+ }
+
+ LiveFileMetaData liveFile = ((RDBStore) sourceStore).getDb()
+ .getLiveFilesMetaData().stream()
+ .max(Comparator.comparingLong(LiveFileMetaData::largestSeqno))
+ .orElseThrow(() -> new IllegalStateException("No live SST file"));
+ Path sourceFile = Paths.get(liveFile.path(), liveFile.fileName());
+ Path deltaFile = tempDir.resolve("delta-" + UUID.randomUUID() + ".sst");
+ Files.createLink(deltaFile, sourceFile);
+ return deltaFile;
+ }
+
+ private void createMockSnapshot(SnapshotInfo snapshotInfo,
+ DBStore snapshotStore) throws IOException {
+ OmSnapshot snapshot = mock(OmSnapshot.class);
+ UncheckedAutoCloseableSupplier snapshotSupplier =
+ new UncheckedAutoCloseableSupplier() {
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public OmSnapshot get() {
+ return snapshot;
+ }
+ };
+ OMMetadataManager snapshotMetadataManager = mock(OMMetadataManager.class);
+ when(snapshot.getMetadataManager()).thenReturn(snapshotMetadataManager);
+ when(snapshotMetadataManager.getStore()).thenReturn(snapshotStore);
+ when(omSnapshotManager.getActiveSnapshot(
+ eq(snapshotInfo.getVolumeName()), eq(snapshotInfo.getBucketName()),
+ eq(snapshotInfo.getName()))).thenReturn(snapshotSupplier);
+ }
+
@AfterEach
public void tearDown() throws Exception {
if (defragService != null) {
@@ -639,12 +716,86 @@ public OmSnapshot get() {
eq(snapshotInfo.getName()))).thenReturn(snapshotSupplier);
}
+ @ParameterizedTest
+ @EnumSource(LiveSstType.class)
+ public void testRewritesSingleLiveSstBeforeIngestion(
+ LiveSstType liveSstType) throws Exception {
+ String tableName = "cf1";
+ String key = "ab001";
+ String previousValue = "previous-value";
+ String currentValue = "current-value";
+ SnapshotInfo previousSnapshotInfo = createMockSnapshotInfo(
+ UUID.randomUUID(), "vol1", "bucket1", "snap1");
+ SnapshotInfo snapshotInfo = createMockSnapshotInfo(
+ UUID.randomUUID(), "vol1", "bucket1", "snap2");
+ TablePrefixInfo prefixInfo = new TablePrefixInfo(
+ ImmutableMap.of(tableName, "ab"));
+
+ try (DBStore sourceStore = createDBStore(
+ "source-" + liveSstType + "-" + UUID.randomUUID(), tableName);
+ DBStore previousStore = createDBStore(
+ "previous-" + liveSstType + "-" + UUID.randomUUID(), tableName);
+ DBStore snapshotStore = createDBStore(
+ "snapshot-" + liveSstType + "-" + UUID.randomUUID(), tableName);
+ DBStore checkpointStore = createDBStore(
+ "checkpoint-" + liveSstType + "-" + UUID.randomUUID(),
+ tableName)) {
+ putString(previousStore.getTable(
+ tableName, StringCodec.get(), CodecBufferCodec.get(true)),
+ key, previousValue);
+ previousStore.flushDB();
+ putString(snapshotStore.getTable(
+ tableName, StringCodec.get(), CodecBufferCodec.get(true)),
+ key, currentValue);
+ snapshotStore.flushDB();
+ createMockSnapshot(previousSnapshotInfo, previousStore);
+ createMockSnapshot(snapshotInfo, snapshotStore);
+ Path deltaFile = createLiveSstDelta(
+ sourceStore, tableName, key, liveSstType);
+ when(deltaFileComputer.getDeltaFiles(eq(previousSnapshotInfo),
+ eq(snapshotInfo), eq(ImmutableSet.of(tableName))))
+ .thenReturn(ImmutableList.of(Pair.of(deltaFile,
+ new SstFileInfo(deltaFile.getFileName().toString(), key, key,
+ tableName))));
+
+ try (MockedConstruction ignored = mockConstruction(
+ SstFileSetReader.class, (mock, context) -> when(mock
+ .getKeyStreamWithTombstone(anyString(), anyString()))
+ .thenReturn(new ClosableIterator() {
+ private boolean hasNext = true;
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public boolean hasNext() {
+ return hasNext;
+ }
+
+ @Override
+ public String next() {
+ hasNext = false;
+ return key;
+ }
+ }))) {
+ defragService.performIncrementalDefragmentation(previousSnapshotInfo,
+ snapshotInfo, 1, checkpointStore, prefixInfo,
+ ImmutableSet.of(tableName));
+ }
+
+ assertEquals(currentValue, checkpointStore.getTable(
+ tableName, StringCodec.get(), StringCodec.get()).get(key));
+ }
+ }
+
/**
* Tests the incremental defragmentation process between two snapshots.
*
* This parameterized test validates the {@code performIncrementalDefragmentation} method
- * across different version scenarios (0, 1, 2, 10) to ensure proper handling of snapshot
- * delta files and version-specific optimizations.
+ * across different version scenarios (0, 1, 2, 10) to ensure all snapshot
+ * delta files are rewritten into fresh external SST files before
+ * ingestion.
*
* Test Data Generation:
* Creates 67,600 synthetic key-value pairs (26×26×100) distributed across two snapshots
@@ -667,26 +818,16 @@ public OmSnapshot get() {
* SstFileSetReader mock returns keys with indices 0-4 (i % 6 < 5)
*
*
- * Version-Specific Behavior:
+ * Expected Behavior:
*
- * - currentVersion == 0 (initial version):
- *
- * - All incremental tables are dumped to new SST files
- * - All dumped files are ingested into the checkpoint database
- *
- *
- * - currentVersion > 0 (subsequent versions):
- *
- * - Single delta file tables (cf1) are ingested directly without merging
- * - Multiple delta file tables (cf2) are merged and dumped before ingestion
- * - Optimization: avoids unnecessary file I/O for single delta files
- *
- *
+ * - Every incremental table is dumped to a fresh external SST file
+ * - All dumped files are ingested into the checkpoint database
+ * - Behavior is independent of snapshot version and delta-file count
*
*
* Assertions:
*
- * - Verifies correct tables are dumped and ingested based on version
+ * - Verifies all incremental tables are dumped and ingested
* - Validates that only modified keys (i % 6 < 3) appear in delta files
* - Confirms written values match snap2's values or null for deletions
* - Ensures all incremental tables are ultimately ingested
@@ -841,16 +982,8 @@ public String next() {
}).when(checkpointDBStore).getTable(anyString());
defragService.performIncrementalDefragmentation(snap1Info, snap2Info, currentVersion, checkpointDBStore,
prefixInfo, incrementalTables);
- if (currentVersion == 0) {
- assertEquals(incrementalTables, new HashSet<>(dumpedFileName.values()));
- assertEquals(ingestedFiles, dumpedFileName);
- } else {
- assertEquals(ImmutableSet.of("cf2"), new HashSet<>(dumpedFileName.values()));
- assertEquals("cf1", ingestedFiles.get(deltaFiles.get(0).getLeft().toAbsolutePath().toString()));
- assertEquals(ingestedFiles.entrySet().stream().filter(e -> e.getValue().equals(
- "cf2")).collect(Collectors.toSet()), dumpedFileName.entrySet().stream().filter(e -> e.getValue().equals(
- "cf2")).collect(Collectors.toSet()));
- }
+ assertEquals(incrementalTables, new HashSet<>(dumpedFileName.values()));
+ assertEquals(ingestedFiles, dumpedFileName);
assertEquals(incrementalTables, new HashSet<>(ingestedFiles.values()));
for (Map.Entry>> deltaFileContent : deltaFileContents.entrySet()) {
int idx = 0;
From ca72a52dc86ee9fb68f4e0ce1b71164e2cdd0837 Mon Sep 17 00:00:00 2001
From: Siyao Meng <50227127+smengcl@users.noreply.github.com>
Date: Tue, 14 Jul 2026 20:55:13 -0700
Subject: [PATCH 2/4] HDDS-15860. Select ingested SST deterministically in test
---
.../defrag/TestSnapshotDefragService.java | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
index dda0f7e2805b..a23928730b84 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
@@ -58,7 +58,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -256,6 +255,10 @@ private Path createLiveSstDelta(DBStore sourceStore, String tableName,
tableName, StringCodec.get(), CodecBufferCodec.get(true));
putString(sourceTable, key, "source-value");
sourceStore.flushDB();
+ Set liveFilesBeforeIngestion = ((RDBStore) sourceStore).getDb()
+ .getLiveFilesMetaData().stream()
+ .map(LiveFileMetaData::fileName)
+ .collect(Collectors.toSet());
if (liveSstType == LiveSstType.PREVIOUSLY_INGESTED) {
File externalFile = tempDir.resolve("external-" + UUID.randomUUID()
@@ -269,10 +272,18 @@ private Path createLiveSstDelta(DBStore sourceStore, String tableName,
sourceTable.loadFromFile(externalFile);
}
- LiveFileMetaData liveFile = ((RDBStore) sourceStore).getDb()
+ List candidateFiles = ((RDBStore) sourceStore).getDb()
.getLiveFilesMetaData().stream()
- .max(Comparator.comparingLong(LiveFileMetaData::largestSeqno))
- .orElseThrow(() -> new IllegalStateException("No live SST file"));
+ .filter(file -> tableName.equals(
+ StringUtils.bytes2String(file.columnFamilyName())))
+ .filter(file -> liveSstType != LiveSstType.PREVIOUSLY_INGESTED ||
+ !liveFilesBeforeIngestion.contains(file.fileName()))
+ .collect(Collectors.toList());
+ if (candidateFiles.size() != 1) {
+ throw new IllegalStateException("Expected one live SST file, found " +
+ candidateFiles.size());
+ }
+ LiveFileMetaData liveFile = candidateFiles.get(0);
Path sourceFile = Paths.get(liveFile.path(), liveFile.fileName());
Path deltaFile = tempDir.resolve("delta-" + UUID.randomUUID() + ".sst");
Files.createLink(deltaFile, sourceFile);
From c45ea869774eec94503997c87039370af04e496d Mon Sep 17 00:00:00 2001
From: Siyao Meng <50227127+smengcl@users.noreply.github.com>
Date: Tue, 14 Jul 2026 21:09:07 -0700
Subject: [PATCH 3/4] HDDS-15860. Fix static analysis issues in defrag test
---
.../defrag/TestSnapshotDefragService.java | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
index a23928730b84..c5b0eb08f563 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
@@ -63,6 +63,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@@ -142,11 +143,6 @@
*/
public class TestSnapshotDefragService {
- private enum LiveSstType {
- DB_GENERATED,
- PREVIOUSLY_INGESTED
- }
-
@Mock
private OzoneManager ozoneManager;
@@ -181,6 +177,11 @@ private enum LiveSstType {
private Map dummyTableValues;
private Set closeSet = new HashSet<>();
+ private enum LiveSstType {
+ DB_GENERATED,
+ PREVIOUSLY_INGESTED
+ }
+
@BeforeEach
public void setup() throws IOException {
mocks = MockitoAnnotations.openMocks(this);
@@ -766,7 +767,7 @@ public void testRewritesSingleLiveSstBeforeIngestion(
when(deltaFileComputer.getDeltaFiles(eq(previousSnapshotInfo),
eq(snapshotInfo), eq(ImmutableSet.of(tableName))))
.thenReturn(ImmutableList.of(Pair.of(deltaFile,
- new SstFileInfo(deltaFile.getFileName().toString(), key, key,
+ new SstFileInfo(deltaFile.toFile().getName(), key, key,
tableName))));
try (MockedConstruction ignored = mockConstruction(
@@ -786,6 +787,9 @@ public boolean hasNext() {
@Override
public String next() {
+ if (!hasNext) {
+ throw new NoSuchElementException();
+ }
hasNext = false;
return key;
}
From 2e6bdbbc692b97e3685bc6ab71072de351fe1aa2 Mon Sep 17 00:00:00 2001
From: Siyao Meng <50227127+smengcl@users.noreply.github.com>
Date: Mon, 20 Jul 2026 08:25:37 -0700
Subject: [PATCH 4/4] HDDS-15860. Remove unused snapshot version parameter
---
.../defrag/SnapshotDefragService.java | 7 +++---
.../defrag/TestSnapshotDefragService.java | 22 ++++++++-----------
2 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/defrag/SnapshotDefragService.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/defrag/SnapshotDefragService.java
index 85b6ea2bfcb9..d96e4869b9d6 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/defrag/SnapshotDefragService.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/defrag/SnapshotDefragService.java
@@ -377,7 +377,6 @@ private Pair spillTableDiffIntoSstFile(List deltaFilePaths,
* @param previousSnapshotInfo information about the previous snapshot.
* @param snapshotInfo information about the current snapshot for which
* incremental defragmentation is performed.
- * @param snapshotVersion the version of the snapshot to be processed.
* @param checkpointStore the dbStore instance where data
* updates are ingested after being processed.
* @param bucketPrefixInfo table prefix information associated with buckets,
@@ -387,7 +386,7 @@ private Pair spillTableDiffIntoSstFile(List deltaFilePaths,
*/
@VisibleForTesting
void performIncrementalDefragmentation(SnapshotInfo previousSnapshotInfo, SnapshotInfo snapshotInfo,
- int snapshotVersion, DBStore checkpointStore, TablePrefixInfo bucketPrefixInfo, Set incrementalTables)
+ DBStore checkpointStore, TablePrefixInfo bucketPrefixInfo, Set incrementalTables)
throws IOException {
// Map of delta files grouped on the basis of the tableName.
Collection> allTableDeltaFiles = this.deltaDiffComputer.getDeltaFiles(
@@ -683,8 +682,8 @@ boolean checkAndDefragSnapshot(SnapshotChainManager chainManager, UUID snapshotI
LOG.info("Performing incremental defragmentation for snapshot: {} (ID: {})", snapshotInfo.getTableKey(),
snapshotInfo.getSnapshotId());
try {
- performIncrementalDefragmentation(checkpointSnapshotInfo, snapshotInfo, needsDefragVersionPair.getValue(),
- checkpointDBStore, prefixInfo, COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT);
+ performIncrementalDefragmentation(checkpointSnapshotInfo, snapshotInfo, checkpointDBStore, prefixInfo,
+ COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT);
perfMetrics.setSnapshotDefragServiceIncLatencyMs(Time.monotonicNow() - defragStart);
} catch (IOException e) {
snapshotMetrics.incNumSnapshotIncDefragFails();
diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
index c5b0eb08f563..99beb715c50c 100644
--- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
+++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/defrag/TestSnapshotDefragService.java
@@ -795,7 +795,7 @@ public String next() {
}
}))) {
defragService.performIncrementalDefragmentation(previousSnapshotInfo,
- snapshotInfo, 1, checkpointStore, prefixInfo,
+ snapshotInfo, checkpointStore, prefixInfo,
ImmutableSet.of(tableName));
}
@@ -807,10 +807,8 @@ public String next() {
/**
* Tests the incremental defragmentation process between two snapshots.
*
- * This parameterized test validates the {@code performIncrementalDefragmentation} method
- * across different version scenarios (0, 1, 2, 10) to ensure all snapshot
- * delta files are rewritten into fresh external SST files before
- * ingestion.
+ * This test validates that all snapshot delta files are rewritten into
+ * fresh external SST files before ingestion.
*
* Test Data Generation:
* Creates 67,600 synthetic key-value pairs (26×26×100) distributed across two snapshots
@@ -848,13 +846,11 @@ public String next() {
* - Ensures all incremental tables are ultimately ingested
*
*
- * @param currentVersion the snapshot version being defragmented (0 for initial, >0 for subsequent)
* @throws Exception if any error occurs during the test execution
*/
@SuppressWarnings("checkstyle:MethodLength")
- @ParameterizedTest
- @ValueSource(ints = {0, 1, 2, 10})
- public void testPerformIncrementalDefragmentation(int currentVersion) throws Exception {
+ @Test
+ public void testPerformIncrementalDefragmentation() throws Exception {
DBStore checkpointDBStore = mock(DBStore.class);
String samePrefix = "samePrefix";
String snap1Prefix = "snap1Prefix";
@@ -995,7 +991,7 @@ public String next() {
String tableName = i.getArgument(0, String.class);
return checkpointTables.get(tableName);
}).when(checkpointDBStore).getTable(anyString());
- defragService.performIncrementalDefragmentation(snap1Info, snap2Info, currentVersion, checkpointDBStore,
+ defragService.performIncrementalDefragmentation(snap1Info, snap2Info, checkpointDBStore,
prefixInfo, incrementalTables);
assertEquals(incrementalTables, new HashSet<>(dumpedFileName.values()));
assertEquals(ingestedFiles, dumpedFileName);
@@ -1086,7 +1082,7 @@ public void testCheckAndDefragSnapshotFailure(boolean previousSnapshotExists) th
IOException defragException = new IOException("Defrag failed");
if (previousSnapshotExists) {
Mockito.doThrow(defragException).when(spyDefragService).performIncrementalDefragmentation(
- eq(previousSnapshotInfo), eq(snapshotInfo), eq(10), eq(checkpointDBStore), eq(prefixInfo),
+ eq(previousSnapshotInfo), eq(snapshotInfo), eq(checkpointDBStore), eq(prefixInfo),
eq(COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT));
} else {
Mockito.doThrow(defragException).when(spyDefragService).performFullDefragmentation(
@@ -1193,7 +1189,7 @@ public void testCheckAndDefragActiveSnapshot(boolean previousSnapshotExists) thr
doNothing().when(spyDefragService).performFullDefragmentation(eq(checkpointDBStore), eq(prefixInfo),
eq(COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT));
doNothing().when(spyDefragService).performIncrementalDefragmentation(eq(previousSnapshotInfo),
- eq(snapshotInfo), eq(10), eq(checkpointDBStore), eq(prefixInfo),
+ eq(snapshotInfo), eq(checkpointDBStore), eq(prefixInfo),
eq(COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT));
AtomicInteger lockAcquired = new AtomicInteger(0);
AtomicInteger lockReleased = new AtomicInteger(0);
@@ -1242,7 +1238,7 @@ public void testCheckAndDefragActiveSnapshot(boolean previousSnapshotExists) thr
eq(COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT));
if (previousSnapshotExists) {
verifier.verify(spyDefragService).performIncrementalDefragmentation(eq(previousSnapshotInfo),
- eq(snapshotInfo), eq(10), eq(checkpointDBStore), eq(prefixInfo),
+ eq(snapshotInfo), eq(checkpointDBStore), eq(prefixInfo),
eq(COLUMN_FAMILIES_TO_TRACK_IN_SNAPSHOT));
} else {
verifier.verify(spyDefragService).performFullDefragmentation(eq(checkpointDBStore), eq(prefixInfo),