@@ -1251,15 +1251,15 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeManualCompaction) {
1251
1251
1252
1252
// pass some time first, otherwise the first a few keys write time are going
1253
1253
// to be zero, and internally zero has special meaning: kUnknownSeqnoTime
1254
- dbfull ()->TEST_WaitForPeridicTaskRun (
1254
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1255
1255
[&] { mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec )); });
1256
1256
1257
1257
int sst_num = 0 ;
1258
1258
// Write files that are overlap and enough to trigger compaction
1259
1259
for (; sst_num < kNumTrigger ; sst_num++) {
1260
1260
for (int i = 0 ; i < kNumKeys ; i++) {
1261
1261
ASSERT_OK (Put (Key (sst_num * (kNumKeys - 1 ) + i), " value" ));
1262
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1262
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1263
1263
mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec ));
1264
1264
});
1265
1265
}
@@ -1313,15 +1313,15 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeAutoCompaction) {
1313
1313
1314
1314
// pass some time first, otherwise the first a few keys write time are going
1315
1315
// to be zero, and internally zero has special meaning: kUnknownSeqnoTime
1316
- dbfull ()->TEST_WaitForPeridicTaskRun (
1316
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1317
1317
[&] { mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec )); });
1318
1318
1319
1319
int sst_num = 0 ;
1320
1320
// Write files that are overlap and enough to trigger compaction
1321
1321
for (; sst_num < kNumTrigger ; sst_num++) {
1322
1322
for (int i = 0 ; i < kNumKeys ; i++) {
1323
1323
ASSERT_OK (Put (Key (sst_num * (kNumKeys - 1 ) + i), " value" ));
1324
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1324
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1325
1325
mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec ));
1326
1326
});
1327
1327
}
@@ -1355,7 +1355,7 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimeAutoCompaction) {
1355
1355
for (int i = 0 ; i < kNumKeys ; i++) {
1356
1356
// the value needs to be big enough to trigger full compaction
1357
1357
ASSERT_OK (Put (Key (sst_num * (kNumKeys - 1 ) + i), rnd.RandomString (100 )));
1358
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1358
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1359
1359
mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec ));
1360
1360
});
1361
1361
}
@@ -1389,15 +1389,15 @@ TEST_F(PrecludeLastLevelTest, MigrationFromPreserveTimePartial) {
1389
1389
1390
1390
// pass some time first, otherwise the first a few keys write time are going
1391
1391
// to be zero, and internally zero has special meaning: kUnknownSeqnoTime
1392
- dbfull ()->TEST_WaitForPeridicTaskRun (
1392
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1393
1393
[&] { mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec )); });
1394
1394
1395
1395
int sst_num = 0 ;
1396
1396
// Write files that are overlap and enough to trigger compaction
1397
1397
for (; sst_num < kNumTrigger ; sst_num++) {
1398
1398
for (int i = 0 ; i < kNumKeys ; i++) {
1399
1399
ASSERT_OK (Put (Key (sst_num * (kNumKeys - 1 ) + i), " value" ));
1400
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1400
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1401
1401
mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec ));
1402
1402
});
1403
1403
}
@@ -1463,13 +1463,13 @@ TEST_F(PrecludeLastLevelTest, SmallPrecludeTime) {
1463
1463
1464
1464
Random rnd (301 );
1465
1465
1466
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1466
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1467
1467
mock_clock_->MockSleepForSeconds (static_cast <int >(rnd.Uniform (10 ) + 1 ));
1468
1468
});
1469
1469
1470
1470
for (int i = 0 ; i < kNumKeys ; i++) {
1471
1471
ASSERT_OK (Put (Key (i), rnd.RandomString (100 )));
1472
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1472
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1473
1473
mock_clock_->MockSleepForSeconds (static_cast <int >(rnd.Uniform (2 )));
1474
1474
});
1475
1475
}
@@ -1516,15 +1516,15 @@ TEST_F(PrecludeLastLevelTest, LastLevelOnlyCompactionPartial) {
1516
1516
1517
1517
// pass some time first, otherwise the first a few keys write time are going
1518
1518
// to be zero, and internally zero has special meaning: kUnknownSeqnoTime
1519
- dbfull ()->TEST_WaitForPeridicTaskRun (
1519
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1520
1520
[&] { mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec )); });
1521
1521
1522
1522
int sst_num = 0 ;
1523
1523
// Write files that are overlap and enough to trigger compaction
1524
1524
for (; sst_num < kNumTrigger ; sst_num++) {
1525
1525
for (int i = 0 ; i < kNumKeys ; i++) {
1526
1526
ASSERT_OK (Put (Key (sst_num * (kNumKeys - 1 ) + i), " value" ));
1527
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1527
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1528
1528
mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec ));
1529
1529
});
1530
1530
}
@@ -1594,7 +1594,7 @@ TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
1594
1594
1595
1595
// pass some time first, otherwise the first a few keys write time are going
1596
1596
// to be zero, and internally zero has special meaning: kUnknownSeqnoTime
1597
- dbfull ()->TEST_WaitForPeridicTaskRun (
1597
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1598
1598
[&] { mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec )); });
1599
1599
1600
1600
Random rnd (301 );
@@ -1603,7 +1603,7 @@ TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
1603
1603
for (; sst_num < kNumTrigger ; sst_num++) {
1604
1604
for (int i = 0 ; i < kNumKeys ; i++) {
1605
1605
ASSERT_OK (Put (Key (sst_num * (kNumKeys - 1 ) + i), rnd.RandomString (100 )));
1606
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1606
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1607
1607
mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec ));
1608
1608
});
1609
1609
}
@@ -1696,7 +1696,7 @@ TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
1696
1696
for (int i = 0 ; i < kNumKeys ; i++) {
1697
1697
// the value needs to be big enough to trigger full compaction
1698
1698
ASSERT_OK (Put (Key (sst_num * (kNumKeys - 1 ) + i), " value" ));
1699
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
1699
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1700
1700
mock_clock_->MockSleepForSeconds (static_cast <int >(kKeyPerSec ));
1701
1701
});
1702
1702
}
@@ -1721,6 +1721,133 @@ TEST_P(PrecludeLastLevelTestWithParms, LastLevelOnlyCompactionNoPreclude) {
1721
1721
Close ();
1722
1722
}
1723
1723
1724
+ TEST_P (PrecludeLastLevelTestWithParms, PeriodicCompactionToPenultimateLevel) {
1725
+ // Test the last level only periodic compaction should also be blocked by an
1726
+ // ongoing compaction in penultimate level if tiered compaction is enabled
1727
+ // otherwise, the periodic compaction should just run for the last level.
1728
+ const int kNumTrigger = 4 ;
1729
+ const int kNumLevels = 7 ;
1730
+ const int kPenultimateLevel = kNumLevels - 2 ;
1731
+ const int kKeyPerSec = 1 ;
1732
+ const int kNumKeys = 100 ;
1733
+
1734
+ bool enable_preclude_last_level = GetParam ();
1735
+
1736
+ Options options = CurrentOptions ();
1737
+ options.compaction_style = kCompactionStyleUniversal ;
1738
+ options.preserve_internal_time_seconds = 20000 ;
1739
+ options.env = mock_env_.get ();
1740
+ options.level0_file_num_compaction_trigger = kNumTrigger ;
1741
+ options.num_levels = kNumLevels ;
1742
+ options.ignore_max_compaction_bytes_for_input = false ;
1743
+ options.periodic_compaction_seconds = 10000 ;
1744
+ DestroyAndReopen (options);
1745
+
1746
+ Random rnd (301 );
1747
+
1748
+ for (int i = 0 ; i < 3 * kNumKeys ; i++) {
1749
+ ASSERT_OK (Put (Key (i), rnd.RandomString (100 )));
1750
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1751
+ [&] { mock_clock_->MockSleepForSeconds (kKeyPerSec ); });
1752
+ }
1753
+ ASSERT_OK (Flush ());
1754
+ CompactRangeOptions cro;
1755
+ cro.bottommost_level_compaction = BottommostLevelCompaction::kForce ;
1756
+
1757
+ ASSERT_OK (db_->CompactRange (cro, nullptr , nullptr ));
1758
+
1759
+ // make sure all data is compacted to the last level
1760
+ ASSERT_EQ (" 0,0,0,0,0,0,1" , FilesPerLevel ());
1761
+
1762
+ // enable preclude feature
1763
+ if (enable_preclude_last_level) {
1764
+ options.preclude_last_level_data_seconds = 20000 ;
1765
+ }
1766
+ options.max_background_jobs = 8 ;
1767
+ options.last_level_temperature = Temperature::kCold ;
1768
+ Reopen (options);
1769
+
1770
+ std::atomic_bool is_size_ratio_compaction_running = false ;
1771
+ std::atomic_bool verified_last_level_compaction = false ;
1772
+
1773
+ SyncPoint::GetInstance ()->SetCallBack (
1774
+ " CompactionJob::ProcessKeyValueCompaction()::Processing" , [&](void * arg) {
1775
+ auto compaction = static_cast <Compaction*>(arg);
1776
+ if (compaction->output_level () == kPenultimateLevel ) {
1777
+ is_size_ratio_compaction_running = true ;
1778
+ TEST_SYNC_POINT (
1779
+ " PrecludeLastLevelTest::PeriodicCompactionToPenultimateLevel:"
1780
+ " SizeRatioCompaction1" );
1781
+ TEST_SYNC_POINT (
1782
+ " PrecludeLastLevelTest::PeriodicCompactionToPenultimateLevel:"
1783
+ " SizeRatioCompaction2" );
1784
+ is_size_ratio_compaction_running = false ;
1785
+ }
1786
+ });
1787
+
1788
+ SyncPoint::GetInstance ()->SetCallBack (
1789
+ " UniversalCompactionBuilder::PickCompaction:Return" , [&](void * arg) {
1790
+ auto compaction = static_cast <Compaction*>(arg);
1791
+
1792
+ if (is_size_ratio_compaction_running) {
1793
+ if (enable_preclude_last_level) {
1794
+ ASSERT_TRUE (compaction == nullptr );
1795
+ } else {
1796
+ ASSERT_TRUE (compaction != nullptr );
1797
+ ASSERT_EQ (compaction->compaction_reason (),
1798
+ CompactionReason::kPeriodicCompaction );
1799
+ ASSERT_EQ (compaction->start_level (), kNumLevels - 1 );
1800
+ }
1801
+ verified_last_level_compaction = true ;
1802
+ }
1803
+ TEST_SYNC_POINT (
1804
+ " PrecludeLastLevelTest::PeriodicCompactionToPenultimateLevel:"
1805
+ " AutoCompactionPicked" );
1806
+ });
1807
+
1808
+ SyncPoint::GetInstance ()->LoadDependency ({
1809
+ {" PrecludeLastLevelTest::PeriodicCompactionToPenultimateLevel:"
1810
+ " SizeRatioCompaction1" ,
1811
+ " PrecludeLastLevelTest::PeriodicCompactionToPenultimateLevel:DoneWrite" },
1812
+ {" PrecludeLastLevelTest::PeriodicCompactionToPenultimateLevel:"
1813
+ " AutoCompactionPicked" ,
1814
+ " PrecludeLastLevelTest::PeriodicCompactionToPenultimateLevel:"
1815
+ " SizeRatioCompaction2" },
1816
+ });
1817
+
1818
+ auto stop_token =
1819
+ dbfull ()->TEST_write_controler ().GetCompactionPressureToken ();
1820
+
1821
+ for (int i = 0 ; i < kNumTrigger - 1 ; i++) {
1822
+ for (int j = 0 ; j < kNumKeys ; j++) {
1823
+ ASSERT_OK (Put (Key (i * (kNumKeys - 1 ) + i), rnd.RandomString (10 )));
1824
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1825
+ [&] { mock_clock_->MockSleepForSeconds (kKeyPerSec ); });
1826
+ }
1827
+ ASSERT_OK (Flush ());
1828
+ }
1829
+
1830
+ TEST_SYNC_POINT (
1831
+ " PrecludeLastLevelTest::PeriodicCompactionToPenultimateLevel:DoneWrite" );
1832
+
1833
+ // wait for periodic compaction time and flush to trigger the periodic
1834
+ // compaction, which should be blocked by ongoing compaction in the
1835
+ // penultimate level
1836
+ mock_clock_->MockSleepForSeconds (10000 );
1837
+ for (int i = 0 ; i < 3 * kNumKeys ; i++) {
1838
+ ASSERT_OK (Put (Key (i), rnd.RandomString (10 )));
1839
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1840
+ [&] { mock_clock_->MockSleepForSeconds (kKeyPerSec ); });
1841
+ }
1842
+ ASSERT_OK (Flush ());
1843
+
1844
+ ASSERT_OK (dbfull ()->WaitForCompact (true ));
1845
+
1846
+ stop_token.reset ();
1847
+
1848
+ Close ();
1849
+ }
1850
+
1724
1851
INSTANTIATE_TEST_CASE_P (PrecludeLastLevelTestWithParms,
1725
1852
PrecludeLastLevelTestWithParms, testing::Bool());
1726
1853
@@ -1781,14 +1908,14 @@ TEST_F(PrecludeLastLevelTest, PartialPenultimateLevelCompaction) {
1781
1908
1782
1909
// pass some time first, otherwise the first a few keys write time are going
1783
1910
// to be zero, and internally zero has special meaning: kUnknownSeqnoTime
1784
- dbfull ()->TEST_WaitForPeridicTaskRun (
1911
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1785
1912
[&] { mock_clock_->MockSleepForSeconds (static_cast <int >(10 )); });
1786
1913
1787
1914
Random rnd (301 );
1788
1915
1789
1916
for (int i = 0 ; i < 300 ; i++) {
1790
1917
ASSERT_OK (Put (Key (i), rnd.RandomString (100 )));
1791
- dbfull ()->TEST_WaitForPeridicTaskRun (
1918
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1792
1919
[&] { mock_clock_->MockSleepForSeconds (kKeyPerSec ); });
1793
1920
}
1794
1921
ASSERT_OK (Flush ());
@@ -1892,7 +2019,7 @@ TEST_F(PrecludeLastLevelTest, RangeDelsCauseFileEndpointsToOverlap) {
1892
2019
1893
2020
// pass some time first, otherwise the first a few keys write time are going
1894
2021
// to be zero, and internally zero has special meaning: kUnknownSeqnoTime
1895
- dbfull ()->TEST_WaitForPeridicTaskRun ([&] {
2022
+ dbfull ()->TEST_WaitForPeriodicTaskRun ([&] {
1896
2023
mock_clock_->MockSleepForSeconds (static_cast <int >(kSecondsPerKey ));
1897
2024
});
1898
2025
@@ -1917,13 +2044,13 @@ TEST_F(PrecludeLastLevelTest, RangeDelsCauseFileEndpointsToOverlap) {
1917
2044
Random rnd (301 );
1918
2045
for (int i = 0 ; i < kNumKeys ; i++) {
1919
2046
ASSERT_OK (Put (Key (i + 3 ), rnd.RandomString (kValueBytes )));
1920
- dbfull ()->TEST_WaitForPeridicTaskRun (
2047
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1921
2048
[&] { mock_clock_->MockSleepForSeconds (kSecondsPerKey ); });
1922
2049
}
1923
2050
auto * snap1 = db_->GetSnapshot ();
1924
2051
for (int i = 0 ; i < kNumKeys ; i++) {
1925
2052
ASSERT_OK (Put (Key (i), rnd.RandomString (kValueBytes )));
1926
- dbfull ()->TEST_WaitForPeridicTaskRun (
2053
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1927
2054
[&] { mock_clock_->MockSleepForSeconds (kSecondsPerKey ); });
1928
2055
}
1929
2056
auto * snap2 = db_->GetSnapshot ();
@@ -1937,7 +2064,7 @@ TEST_F(PrecludeLastLevelTest, RangeDelsCauseFileEndpointsToOverlap) {
1937
2064
Key (2 * kNumKeysPerFile - 1 ),
1938
2065
Key (2 * kNumKeysPerFile + 1 )));
1939
2066
ASSERT_OK (Flush ());
1940
- dbfull ()->TEST_WaitForPeridicTaskRun (
2067
+ dbfull ()->TEST_WaitForPeriodicTaskRun (
1941
2068
[&] { mock_clock_->MockSleepForSeconds (kSecondsPerKey ); });
1942
2069
verify_db ();
1943
2070
0 commit comments