summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/compaction/compaction_iterator.cc27
-rw-r--r--db/compaction/tiered_compaction_test.cc25
2 files changed, 41 insertions, 11 deletions
diff --git a/db/compaction/compaction_iterator.cc b/db/compaction/compaction_iterator.cc
index bc19de8ec..60592489b 100644
--- a/db/compaction/compaction_iterator.cc
+++ b/db/compaction/compaction_iterator.cc
@@ -1280,6 +1280,21 @@ void CompactionIterator::DecideOutputLevel() {
}
#endif // NDEBUG
+ // saved_seq_for_penul_check_ is populated in `NextFromInput` when the
+ // entry's sequence number is non zero and validity context for output this
+ // entry is kSwapPreferredSeqno for use in `DecideOutputLevel`. It should be
+ // cleared out here unconditionally. Otherwise, it may end up getting consumed
+ // incorrectly by a different entry.
+ SequenceNumber seq_for_range_check =
+ (saved_seq_for_penul_check_.has_value() &&
+ saved_seq_for_penul_check_.value() != kMaxSequenceNumber)
+ ? saved_seq_for_penul_check_.value()
+ : ikey_.sequence;
+ saved_seq_for_penul_check_ = std::nullopt;
+ ParsedInternalKey ikey_for_range_check = ikey_;
+ if (seq_for_range_check != ikey_.sequence) {
+ ikey_for_range_check.sequence = seq_for_range_check;
+ }
if (output_to_penultimate_level_) {
// If it's decided to output to the penultimate level, but unsafe to do so,
// still output to the last level. For example, moving the data from a lower
@@ -1287,16 +1302,6 @@ void CompactionIterator::DecideOutputLevel() {
// considered unsafe, because the key may conflict with higher-level SSTs
// not from this compaction.
// TODO: add statistic for declined output_to_penultimate_level
- SequenceNumber seq_for_range_check =
- (saved_seq_for_penul_check_.has_value() &&
- saved_seq_for_penul_check_.value() != kMaxSequenceNumber)
- ? saved_seq_for_penul_check_.value()
- : ikey_.sequence;
- ParsedInternalKey ikey_for_range_check = ikey_;
- if (seq_for_range_check != ikey_.sequence) {
- ikey_for_range_check.sequence = seq_for_range_check;
- saved_seq_for_penul_check_ = std::nullopt;
- }
bool safe_to_penultimate_level =
compaction_->WithinPenultimateLevelOutputRange(ikey_for_range_check);
if (!safe_to_penultimate_level) {
@@ -1310,7 +1315,7 @@ void CompactionIterator::DecideOutputLevel() {
// snapshot is released before enabling `last_level_temperature` feature
// We will migrate the feature to `last_level_temperature` and maybe make
// it not dynamically changeable.
- if (ikey_.sequence > earliest_snapshot_) {
+ if (seq_for_range_check > earliest_snapshot_) {
status_ = Status::Corruption(
"Unsafe to store Seq later than snapshot in the last level if "
"per_key_placement is enabled");
diff --git a/db/compaction/tiered_compaction_test.cc b/db/compaction/tiered_compaction_test.cc
index d8b48b991..c99db9850 100644
--- a/db/compaction/tiered_compaction_test.cc
+++ b/db/compaction/tiered_compaction_test.cc
@@ -1651,6 +1651,31 @@ TEST_P(TimedPutPrecludeLastLevelTest, FastTrackTimedPutToLastLevel) {
Close();
}
+TEST_P(TimedPutPrecludeLastLevelTest, InterleavedTimedPutAndPut) {
+ Options options = CurrentOptions();
+ options.compaction_style = kCompactionStyleUniversal;
+ options.disable_auto_compactions = true;
+ options.preclude_last_level_data_seconds = 1 * 24 * 60 * 60;
+ options.env = mock_env_.get();
+ options.num_levels = 7;
+ options.last_level_temperature = Temperature::kCold;
+ options.default_write_temperature = Temperature::kHot;
+ DestroyAndReopen(options);
+ WriteOptions wo;
+ wo.protection_bytes_per_key = GetParam();
+
+ // Start time: kMockStartTime = 10000000;
+ ASSERT_OK(TimedPut(0, Key(0), "v0", kMockStartTime - 1 * 24 * 60 * 60, wo));
+ ASSERT_OK(Put(Key(1), "v1", wo));
+ ASSERT_OK(Flush());
+
+ ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
+ ASSERT_EQ("0,0,0,0,0,1,1", FilesPerLevel());
+ ASSERT_GT(GetSstSizeHelper(Temperature::kHot), 0);
+ ASSERT_GT(GetSstSizeHelper(Temperature::kCold), 0);
+ Close();
+}
+
TEST_P(TimedPutPrecludeLastLevelTest, PreserveTimedPutOnPenultimateLevel) {
Options options = CurrentOptions();
options.compaction_style = kCompactionStyleUniversal;