diff --git a/hadoop-hdds/rocksdb-checkpoint-differ/src/main/java/org/apache/ozone/rocksdiff/RocksDBCheckpointDiffer.java b/hadoop-hdds/rocksdb-checkpoint-differ/src/main/java/org/apache/ozone/rocksdiff/RocksDBCheckpointDiffer.java index 5e612d8b204d..0b7c8e376d3a 100644 --- a/hadoop-hdds/rocksdb-checkpoint-differ/src/main/java/org/apache/ozone/rocksdiff/RocksDBCheckpointDiffer.java +++ b/hadoop-hdds/rocksdb-checkpoint-differ/src/main/java/org/apache/ozone/rocksdiff/RocksDBCheckpointDiffer.java @@ -587,7 +587,7 @@ void addToCompactionLogTable(CompactionLogEntry compactionLogEntry) { * Check if there is any in_progress tarball creation request and wait till * all tarball creation finish, and it gets notified. */ - private void waitForTarballCreation() { + private synchronized void waitForTarballCreation() { while (tarballRequestCount.get() != 0) { try { wait(Integer.MAX_VALUE); diff --git a/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/ozone/rocksdiff/TestRocksDBCheckpointDiffer.java b/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/ozone/rocksdiff/TestRocksDBCheckpointDiffer.java index 6dded6cb57f2..138463eb1163 100644 --- a/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/ozone/rocksdiff/TestRocksDBCheckpointDiffer.java +++ b/hadoop-hdds/rocksdb-checkpoint-differ/src/test/java/org/apache/ozone/rocksdiff/TestRocksDBCheckpointDiffer.java @@ -1947,4 +1947,54 @@ public void testShouldSkipFile(String description, assertEquals(expectedResult, rocksDBCheckpointDiffer .shouldSkipCompaction(columnFamilyBytes, inputFiles, outputFiles)); } + + /** + * Test to verify that no compaction log entry is added to compactionLogTable and DAG. + */ + @Test + void testCompactionLogsAreNotAppendedIfTarballCreationIsInProgress() throws Exception { + rocksDBCheckpointDiffer.setSnapshotInfoTableCFHandle(keyTableCFHandle); + + // Increment tarball request count twice to mimic that two tarball requests are in progress, + // so the compaction thread waits. + rocksDBCheckpointDiffer.incrementTarballRequestCount(); + rocksDBCheckpointDiffer.incrementTarballRequestCount(); + assertEquals(2, rocksDBCheckpointDiffer.getTarballRequestCount()); + + writeKeysAndCheckpointing(); + Thread.sleep(1000); + + // Verify that no log entry gets added to compactionLogTable and DAG when tarball request count is not zero. + assertCompactionTableAndDagEntries(0, 0, 0); + + // Release one tarball request by decrementing tarball request count. + rocksDBCheckpointDiffer.decrementTarballRequestCountAndNotify(); + assertEquals(1, rocksDBCheckpointDiffer.getTarballRequestCount()); + + Thread.sleep(1000); + + // Verify again that no log entry gets added to compactionLogTable and DAG after decrementing tarball request count, + // but it is still non-zero. + assertCompactionTableAndDagEntries(0, 0, 0); + + // Release the second tarball request by decrementing tarball request count again, + // so the compaction thread can continue. + rocksDBCheckpointDiffer.decrementTarballRequestCountAndNotify(); + + assertEquals(0, rocksDBCheckpointDiffer.getTarballRequestCount()); + GenericTestUtils.waitFor(() -> countEntriesInCompactionLogTable() == 1, 100, 1000); + + // Verify that log entries get added to compactionLogTable and DAG after only tarball request count reaches zero. + assertCompactionTableAndDagEntries(1, 5, 4); + cleanUpSnapshots(); + } + + private void assertCompactionTableAndDagEntries(int expectedEntriesInCompactionLogTable, + int expectedNodesInCompactionDag, + int expectedArcsInCompactionDag) { + + assertEquals(expectedEntriesInCompactionLogTable, countEntriesInCompactionLogTable()); + assertEquals(expectedNodesInCompactionDag, rocksDBCheckpointDiffer.getForwardCompactionDAG().nodes().size()); + assertEquals(expectedArcsInCompactionDag, rocksDBCheckpointDiffer.getForwardCompactionDAG().edges().size()); + } }